]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/exp_ch4.adb
Minor reformatting.
[thirdparty/gcc.git] / gcc / ada / exp_ch4.adb
CommitLineData
70482933
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- E X P _ C H 4 --
59262ebb 6-- --
70482933
RK
7-- B o d y --
8-- --
760804f3 9-- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
70482933
RK
10-- --
11-- GNAT is free software; you can redistribute it and/or modify it under --
12-- terms of the GNU General Public License as published by the Free Soft- --
b5c84c3c 13-- ware Foundation; either version 3, or (at your option) any later ver- --
70482933
RK
14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17-- for more details. You should have received a copy of the GNU General --
b5c84c3c
RD
18-- Public License distributed with GNAT; see file COPYING3. If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license. --
70482933
RK
20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
70482933
RK
23-- --
24------------------------------------------------------------------------------
25
26with Atree; use Atree;
27with Checks; use Checks;
bded454f 28with Debug; use Debug;
70482933
RK
29with Einfo; use Einfo;
30with Elists; use Elists;
31with Errout; use Errout;
32with Exp_Aggr; use Exp_Aggr;
0669bebe 33with Exp_Atag; use Exp_Atag;
6cce2156 34with Exp_Ch2; use Exp_Ch2;
70482933 35with Exp_Ch3; use Exp_Ch3;
20b5d666 36with Exp_Ch6; use Exp_Ch6;
70482933
RK
37with Exp_Ch7; use Exp_Ch7;
38with Exp_Ch9; use Exp_Ch9;
20b5d666 39with Exp_Disp; use Exp_Disp;
70482933 40with Exp_Fixd; use Exp_Fixd;
437f8c1e 41with Exp_Intr; use Exp_Intr;
70482933
RK
42with Exp_Pakd; use Exp_Pakd;
43with Exp_Tss; use Exp_Tss;
44with Exp_Util; use Exp_Util;
f02b8bb8 45with Freeze; use Freeze;
70482933 46with Inline; use Inline;
df3e68b1 47with Lib; use Lib;
26bff3d9 48with Namet; use Namet;
70482933
RK
49with Nlists; use Nlists;
50with Nmake; use Nmake;
51with Opt; use Opt;
25adc5fb 52with Par_SCO; use Par_SCO;
0669bebe
GB
53with Restrict; use Restrict;
54with Rident; use Rident;
70482933
RK
55with Rtsfind; use Rtsfind;
56with Sem; use Sem;
a4100e55 57with Sem_Aux; use Sem_Aux;
70482933 58with Sem_Cat; use Sem_Cat;
5d09245e 59with Sem_Ch3; use Sem_Ch3;
11fa950b 60with Sem_Ch8; use Sem_Ch8;
70482933
RK
61with Sem_Ch13; use Sem_Ch13;
62with Sem_Eval; use Sem_Eval;
63with Sem_Res; use Sem_Res;
64with Sem_Type; use Sem_Type;
65with Sem_Util; use Sem_Util;
07fc65c4 66with Sem_Warn; use Sem_Warn;
70482933 67with Sinfo; use Sinfo;
70482933
RK
68with Snames; use Snames;
69with Stand; use Stand;
7665e4bd 70with SCIL_LL; use SCIL_LL;
07fc65c4 71with Targparm; use Targparm;
70482933
RK
72with Tbuild; use Tbuild;
73with Ttypes; use Ttypes;
74with Uintp; use Uintp;
75with Urealp; use Urealp;
76with Validsw; use Validsw;
77
78package body Exp_Ch4 is
79
15ce9ca2
AC
80 -----------------------
81 -- Local Subprograms --
82 -----------------------
70482933
RK
83
84 procedure Binary_Op_Validity_Checks (N : Node_Id);
85 pragma Inline (Binary_Op_Validity_Checks);
86 -- Performs validity checks for a binary operator
87
fbf5a39b
AC
88 procedure Build_Boolean_Array_Proc_Call
89 (N : Node_Id;
90 Op1 : Node_Id;
91 Op2 : Node_Id);
303b4d58 92 -- If a boolean array assignment can be done in place, build call to
fbf5a39b
AC
93 -- corresponding library procedure.
94
11fa950b
AC
95 function Current_Anonymous_Master return Entity_Id;
96 -- Return the entity of the heterogeneous finalization master belonging to
97 -- the current unit (either function, package or procedure). This master
98 -- services all anonymous access-to-controlled types. If the current unit
99 -- does not have such master, create one.
df3e68b1 100
26bff3d9
JM
101 procedure Displace_Allocator_Pointer (N : Node_Id);
102 -- Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
103 -- Expand_Allocator_Expression. Allocating class-wide interface objects
104 -- this routine displaces the pointer to the allocated object to reference
105 -- the component referencing the corresponding secondary dispatch table.
106
fbf5a39b
AC
107 procedure Expand_Allocator_Expression (N : Node_Id);
108 -- Subsidiary to Expand_N_Allocator, for the case when the expression
109 -- is a qualified expression or an aggregate.
110
70482933
RK
111 procedure Expand_Array_Comparison (N : Node_Id);
112 -- This routine handles expansion of the comparison operators (N_Op_Lt,
113 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
114 -- code for these operators is similar, differing only in the details of
fbf5a39b
AC
115 -- the actual comparison call that is made. Special processing (call a
116 -- run-time routine)
70482933
RK
117
118 function Expand_Array_Equality
119 (Nod : Node_Id;
70482933
RK
120 Lhs : Node_Id;
121 Rhs : Node_Id;
0da2c8ac
AC
122 Bodies : List_Id;
123 Typ : Entity_Id) return Node_Id;
70482933 124 -- Expand an array equality into a call to a function implementing this
685094bf
RD
125 -- equality, and a call to it. Loc is the location for the generated nodes.
126 -- Lhs and Rhs are the array expressions to be compared. Bodies is a list
127 -- on which to attach bodies of local functions that are created in the
128 -- process. It is the responsibility of the caller to insert those bodies
129 -- at the right place. Nod provides the Sloc value for the generated code.
130 -- Normally the types used for the generated equality routine are taken
131 -- from Lhs and Rhs. However, in some situations of generated code, the
132 -- Etype fields of Lhs and Rhs are not set yet. In such cases, Typ supplies
133 -- the type to be used for the formal parameters.
70482933
RK
134
135 procedure Expand_Boolean_Operator (N : Node_Id);
685094bf
RD
136 -- Common expansion processing for Boolean operators (And, Or, Xor) for the
137 -- case of array type arguments.
70482933 138
5875f8d6
AC
139 procedure Expand_Short_Circuit_Operator (N : Node_Id);
140 -- Common expansion processing for short-circuit boolean operators
141
456cbfa5 142 procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id);
5707e389
AC
143 -- Deal with comparison in MINIMIZED/ELIMINATED overflow mode. This is
144 -- where we allow comparison of "out of range" values.
456cbfa5 145
70482933
RK
146 function Expand_Composite_Equality
147 (Nod : Node_Id;
148 Typ : Entity_Id;
149 Lhs : Node_Id;
150 Rhs : Node_Id;
2e071734 151 Bodies : List_Id) return Node_Id;
685094bf
RD
152 -- Local recursive function used to expand equality for nested composite
153 -- types. Used by Expand_Record/Array_Equality, Bodies is a list on which
d26d790d
AC
154 -- to attach bodies of local functions that are created in the process. It
155 -- is the responsibility of the caller to insert those bodies at the right
156 -- place. Nod provides the Sloc value for generated code. Lhs and Rhs are
157 -- the left and right sides for the comparison, and Typ is the type of the
158 -- objects to compare.
70482933 159
fdac1f80
AC
160 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id);
161 -- Routine to expand concatenation of a sequence of two or more operands
162 -- (in the list Operands) and replace node Cnode with the result of the
163 -- concatenation. The operands can be of any appropriate type, and can
164 -- include both arrays and singleton elements.
70482933 165
f6194278 166 procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id);
5707e389
AC
167 -- N is an N_In membership test mode, with the overflow check mode set to
168 -- MINIMIZED or ELIMINATED, and the type of the left operand is a signed
169 -- integer type. This is a case where top level processing is required to
170 -- handle overflow checks in subtrees.
f6194278 171
70482933 172 procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
685094bf
RD
173 -- N is a N_Op_Divide or N_Op_Multiply node whose result is universal
174 -- fixed. We do not have such a type at runtime, so the purpose of this
175 -- routine is to find the real type by looking up the tree. We also
176 -- determine if the operation must be rounded.
70482933 177
5d09245e
AC
178 function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
179 -- Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
180 -- discriminants if it has a constrained nominal type, unless the object
181 -- is a component of an enclosing Unchecked_Union object that is subject
182 -- to a per-object constraint and the enclosing object lacks inferable
183 -- discriminants.
184 --
185 -- An expression of an Unchecked_Union type has inferable discriminants
186 -- if it is either a name of an object with inferable discriminants or a
187 -- qualified expression whose subtype mark denotes a constrained subtype.
188
70482933 189 procedure Insert_Dereference_Action (N : Node_Id);
e6f69614
AC
190 -- N is an expression whose type is an access. When the type of the
191 -- associated storage pool is derived from Checked_Pool, generate a
192 -- call to the 'Dereference' primitive operation.
70482933
RK
193
194 function Make_Array_Comparison_Op
2e071734
AC
195 (Typ : Entity_Id;
196 Nod : Node_Id) return Node_Id;
685094bf
RD
197 -- Comparisons between arrays are expanded in line. This function produces
198 -- the body of the implementation of (a > b), where a and b are one-
199 -- dimensional arrays of some discrete type. The original node is then
200 -- expanded into the appropriate call to this function. Nod provides the
201 -- Sloc value for the generated code.
70482933
RK
202
203 function Make_Boolean_Array_Op
2e071734
AC
204 (Typ : Entity_Id;
205 N : Node_Id) return Node_Id;
685094bf
RD
206 -- Boolean operations on boolean arrays are expanded in line. This function
207 -- produce the body for the node N, which is (a and b), (a or b), or (a xor
208 -- b). It is used only the normal case and not the packed case. The type
209 -- involved, Typ, is the Boolean array type, and the logical operations in
210 -- the body are simple boolean operations. Note that Typ is always a
211 -- constrained type (the caller has ensured this by using
212 -- Convert_To_Actual_Subtype if necessary).
70482933 213
b6b5cca8 214 function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean;
a7f1b24f
RD
215 -- For signed arithmetic operations when the current overflow mode is
216 -- MINIMIZED or ELIMINATED, we must call Apply_Arithmetic_Overflow_Checks
217 -- as the first thing we do. We then return. We count on the recursive
218 -- apparatus for overflow checks to call us back with an equivalent
219 -- operation that is in CHECKED mode, avoiding a recursive entry into this
220 -- routine, and that is when we will proceed with the expansion of the
221 -- operator (e.g. converting X+0 to X, or X**2 to X*X). We cannot do
222 -- these optimizations without first making this check, since there may be
223 -- operands further down the tree that are relying on the recursive calls
224 -- triggered by the top level nodes to properly process overflow checking
225 -- and remaining expansion on these nodes. Note that this call back may be
226 -- skipped if the operation is done in Bignum mode but that's fine, since
227 -- the Bignum call takes care of everything.
b6b5cca8 228
0580d807
AC
229 procedure Optimize_Length_Comparison (N : Node_Id);
230 -- Given an expression, if it is of the form X'Length op N (or the other
231 -- way round), where N is known at compile time to be 0 or 1, and X is a
232 -- simple entity, and op is a comparison operator, optimizes it into a
233 -- comparison of First and Last.
234
b2c28399
AC
235 procedure Process_Transient_Object
236 (Decl : Node_Id;
237 Rel_Node : Node_Id);
238 -- Subsidiary routine to the expansion of expression_with_actions and if
239 -- expressions. Generate all the necessary code to finalize a transient
240 -- controlled object when the enclosing context is elaborated or evaluated.
241 -- Decl denotes the declaration of the transient controlled object which is
242 -- usually the result of a controlled function call. Rel_Node denotes the
243 -- context, either an expression_with_actions or an if expression.
244
70482933 245 procedure Rewrite_Comparison (N : Node_Id);
20b5d666 246 -- If N is the node for a comparison whose outcome can be determined at
d26dc4b5
AC
247 -- compile time, then the node N can be rewritten with True or False. If
248 -- the outcome cannot be determined at compile time, the call has no
249 -- effect. If N is a type conversion, then this processing is applied to
250 -- its expression. If N is neither comparison nor a type conversion, the
251 -- call has no effect.
70482933 252
82878151
AC
253 procedure Tagged_Membership
254 (N : Node_Id;
255 SCIL_Node : out Node_Id;
256 Result : out Node_Id);
70482933
RK
257 -- Construct the expression corresponding to the tagged membership test.
258 -- Deals with a second operand being (or not) a class-wide type.
259
fbf5a39b 260 function Safe_In_Place_Array_Op
2e071734
AC
261 (Lhs : Node_Id;
262 Op1 : Node_Id;
263 Op2 : Node_Id) return Boolean;
685094bf
RD
264 -- In the context of an assignment, where the right-hand side is a boolean
265 -- operation on arrays, check whether operation can be performed in place.
fbf5a39b 266
70482933
RK
267 procedure Unary_Op_Validity_Checks (N : Node_Id);
268 pragma Inline (Unary_Op_Validity_Checks);
269 -- Performs validity checks for a unary operator
270
271 -------------------------------
272 -- Binary_Op_Validity_Checks --
273 -------------------------------
274
275 procedure Binary_Op_Validity_Checks (N : Node_Id) is
276 begin
277 if Validity_Checks_On and Validity_Check_Operands then
278 Ensure_Valid (Left_Opnd (N));
279 Ensure_Valid (Right_Opnd (N));
280 end if;
281 end Binary_Op_Validity_Checks;
282
fbf5a39b
AC
283 ------------------------------------
284 -- Build_Boolean_Array_Proc_Call --
285 ------------------------------------
286
287 procedure Build_Boolean_Array_Proc_Call
288 (N : Node_Id;
289 Op1 : Node_Id;
290 Op2 : Node_Id)
291 is
292 Loc : constant Source_Ptr := Sloc (N);
293 Kind : constant Node_Kind := Nkind (Expression (N));
294 Target : constant Node_Id :=
295 Make_Attribute_Reference (Loc,
296 Prefix => Name (N),
297 Attribute_Name => Name_Address);
298
bed8af19 299 Arg1 : Node_Id := Op1;
fbf5a39b
AC
300 Arg2 : Node_Id := Op2;
301 Call_Node : Node_Id;
302 Proc_Name : Entity_Id;
303
304 begin
305 if Kind = N_Op_Not then
306 if Nkind (Op1) in N_Binary_Op then
307
5e1c00fa 308 -- Use negated version of the binary operators
fbf5a39b
AC
309
310 if Nkind (Op1) = N_Op_And then
311 Proc_Name := RTE (RE_Vector_Nand);
312
313 elsif Nkind (Op1) = N_Op_Or then
314 Proc_Name := RTE (RE_Vector_Nor);
315
316 else pragma Assert (Nkind (Op1) = N_Op_Xor);
317 Proc_Name := RTE (RE_Vector_Xor);
318 end if;
319
320 Call_Node :=
321 Make_Procedure_Call_Statement (Loc,
322 Name => New_Occurrence_Of (Proc_Name, Loc),
323
324 Parameter_Associations => New_List (
325 Target,
326 Make_Attribute_Reference (Loc,
327 Prefix => Left_Opnd (Op1),
328 Attribute_Name => Name_Address),
329
330 Make_Attribute_Reference (Loc,
331 Prefix => Right_Opnd (Op1),
332 Attribute_Name => Name_Address),
333
334 Make_Attribute_Reference (Loc,
335 Prefix => Left_Opnd (Op1),
336 Attribute_Name => Name_Length)));
337
338 else
339 Proc_Name := RTE (RE_Vector_Not);
340
341 Call_Node :=
342 Make_Procedure_Call_Statement (Loc,
343 Name => New_Occurrence_Of (Proc_Name, Loc),
344 Parameter_Associations => New_List (
345 Target,
346
347 Make_Attribute_Reference (Loc,
348 Prefix => Op1,
349 Attribute_Name => Name_Address),
350
351 Make_Attribute_Reference (Loc,
352 Prefix => Op1,
353 Attribute_Name => Name_Length)));
354 end if;
355
356 else
357 -- We use the following equivalences:
358
359 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
360 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
361 -- (not X) xor (not Y) = X xor Y
362 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
363
364 if Nkind (Op1) = N_Op_Not then
bed8af19
AC
365 Arg1 := Right_Opnd (Op1);
366 Arg2 := Right_Opnd (Op2);
533369aa 367
fbf5a39b
AC
368 if Kind = N_Op_And then
369 Proc_Name := RTE (RE_Vector_Nor);
fbf5a39b
AC
370 elsif Kind = N_Op_Or then
371 Proc_Name := RTE (RE_Vector_Nand);
fbf5a39b
AC
372 else
373 Proc_Name := RTE (RE_Vector_Xor);
374 end if;
375
376 else
377 if Kind = N_Op_And then
378 Proc_Name := RTE (RE_Vector_And);
fbf5a39b
AC
379 elsif Kind = N_Op_Or then
380 Proc_Name := RTE (RE_Vector_Or);
fbf5a39b
AC
381 elsif Nkind (Op2) = N_Op_Not then
382 Proc_Name := RTE (RE_Vector_Nxor);
383 Arg2 := Right_Opnd (Op2);
fbf5a39b
AC
384 else
385 Proc_Name := RTE (RE_Vector_Xor);
386 end if;
387 end if;
388
389 Call_Node :=
390 Make_Procedure_Call_Statement (Loc,
391 Name => New_Occurrence_Of (Proc_Name, Loc),
392 Parameter_Associations => New_List (
393 Target,
955871d3
AC
394 Make_Attribute_Reference (Loc,
395 Prefix => Arg1,
396 Attribute_Name => Name_Address),
397 Make_Attribute_Reference (Loc,
398 Prefix => Arg2,
399 Attribute_Name => Name_Address),
400 Make_Attribute_Reference (Loc,
a8ef12e5 401 Prefix => Arg1,
955871d3 402 Attribute_Name => Name_Length)));
fbf5a39b
AC
403 end if;
404
405 Rewrite (N, Call_Node);
406 Analyze (N);
407
408 exception
409 when RE_Not_Available =>
410 return;
411 end Build_Boolean_Array_Proc_Call;
412
11fa950b
AC
413 ------------------------------
414 -- Current_Anonymous_Master --
415 ------------------------------
df3e68b1 416
11fa950b 417 function Current_Anonymous_Master return Entity_Id is
57ae790f
HK
418 function Create_Anonymous_Master
419 (Unit_Id : Entity_Id;
420 Decls : List_Id) return Entity_Id;
421 -- Create a new anonymous finalization master for a unit denoted by
422 -- Unit_Id. The declaration of the master along with any specialized
423 -- initialization is inserted at the top of declarative list Decls.
424 -- Return the entity of the anonymous master.
425
426 -----------------------------
427 -- Create_Anonymous_Master --
428 -----------------------------
429
430 function Create_Anonymous_Master
431 (Unit_Id : Entity_Id;
432 Decls : List_Id) return Entity_Id
433 is
434 First_Decl : Node_Id := Empty;
435 -- The first declaration of list Decls. This variable is used when
436 -- inserting various actions.
437
438 procedure Insert_And_Analyze (Action : Node_Id);
439 -- Insert arbitrary node Action in declarative list Decl and analyze
440 -- it.
441
442 ------------------------
443 -- Insert_And_Analyze --
444 ------------------------
445
446 procedure Insert_And_Analyze (Action : Node_Id) is
447 begin
448 -- The list is already populated, the actions are inserted at the
449 -- top of the list, preserving their order.
11fa950b 450
57ae790f
HK
451 if Present (First_Decl) then
452 Insert_Before_And_Analyze (First_Decl, Action);
11fa950b 453
57ae790f 454 -- Otherwise append to the declarations to preserve order
df3e68b1 455
57ae790f
HK
456 else
457 Append_To (Decls, Action);
458 Analyze (Action);
459 end if;
460 end Insert_And_Analyze;
df3e68b1 461
57ae790f 462 -- Local variables
df3e68b1 463
57ae790f
HK
464 Loc : constant Source_Ptr := Sloc (Unit_Id);
465 FM_Id : Entity_Id;
f553e7bc 466
57ae790f 467 -- Start of processing for Create_Anonymous_Master
df3e68b1 468
57ae790f
HK
469 begin
470 if Present (Decls) then
471 First_Decl := First (Decls);
ca5af305 472 end if;
df3e68b1 473
57ae790f
HK
474 -- Since the anonymous master and all its initialization actions are
475 -- inserted at top level, use the scope of the unit when analyzing.
2c17ca0a 476
57ae790f 477 Push_Scope (Unit_Id);
2c17ca0a 478
57ae790f 479 -- Create the anonymous master
2c17ca0a 480
57ae790f
HK
481 FM_Id :=
482 Make_Defining_Identifier (Loc,
483 Chars => New_External_Name (Chars (Unit_Id), "AM"));
484 Set_Anonymous_Master (Unit_Id, FM_Id);
df3e68b1 485
57ae790f
HK
486 -- Generate:
487 -- <FM_Id> : Finalization_Master;
11fa950b 488
57ae790f
HK
489 Insert_And_Analyze
490 (Make_Object_Declaration (Loc,
491 Defining_Identifier => FM_Id,
492 Object_Definition =>
493 New_Occurrence_Of (RTE (RE_Finalization_Master), Loc)));
11fa950b 494
57ae790f
HK
495 -- Do not set the base pool and mode of operation on .NET/JVM since
496 -- those targets do not support pools and all VM masters defaulted to
497 -- heterogeneous.
11fa950b 498
57ae790f 499 if VM_Target = No_VM then
11fa950b 500
57ae790f
HK
501 -- Generate:
502 -- Set_Base_Pool
503 -- (<FM_Id>, Global_Pool_Object'Unrestricted_Access);
11fa950b 504
57ae790f
HK
505 Insert_And_Analyze
506 (Make_Procedure_Call_Statement (Loc,
507 Name =>
508 New_Occurrence_Of (RTE (RE_Set_Base_Pool), Loc),
509 Parameter_Associations => New_List (
510 New_Occurrence_Of (FM_Id, Loc),
511 Make_Attribute_Reference (Loc,
512 Prefix =>
513 New_Occurrence_Of (RTE (RE_Global_Pool_Object), Loc),
514 Attribute_Name => Name_Unrestricted_Access))));
11fa950b
AC
515
516 -- Generate:
57ae790f 517 -- Set_Is_Heterogeneous (<FM_Id>);
11fa950b 518
57ae790f
HK
519 Insert_And_Analyze
520 (Make_Procedure_Call_Statement (Loc,
521 Name =>
522 New_Occurrence_Of (RTE (RE_Set_Is_Heterogeneous), Loc),
523 Parameter_Associations => New_List (
524 New_Occurrence_Of (FM_Id, Loc))));
525 end if;
11fa950b 526
57ae790f 527 Pop_Scope;
57ae790f
HK
528 return FM_Id;
529 end Create_Anonymous_Master;
11fa950b 530
57ae790f 531 -- Local declarations
11fa950b 532
57ae790f
HK
533 Unit_Decl : constant Node_Id := Unit (Cunit (Current_Sem_Unit));
534 Unit_Id : constant Entity_Id := Corresponding_Spec_Of (Unit_Decl);
535 Decls : List_Id;
536 FM_Id : Entity_Id;
537 Unit_Spec : Node_Id;
11fa950b 538
57ae790f 539 -- Start of processing for Current_Anonymous_Master
11fa950b 540
57ae790f
HK
541 begin
542 FM_Id := Anonymous_Master (Unit_Id);
11fa950b 543
57ae790f
HK
544 -- Create a new anonymous master when allocating an object of anonymous
545 -- access-to-controlled type for the first time.
11fa950b 546
57ae790f 547 if No (FM_Id) then
11fa950b 548
57ae790f 549 -- Find the declarative list of the current unit
11fa950b 550
57ae790f
HK
551 if Nkind (Unit_Decl) = N_Package_Declaration then
552 Unit_Spec := Specification (Unit_Decl);
553 Decls := Visible_Declarations (Unit_Spec);
11fa950b 554
57ae790f
HK
555 if No (Decls) then
556 Decls := New_List;
557 Set_Visible_Declarations (Unit_Spec, Decls);
11fa950b
AC
558 end if;
559
57ae790f 560 -- Package or subprogram body
11fa950b 561
57ae790f
HK
562 else
563 Decls := Declarations (Unit_Decl);
11fa950b 564
57ae790f
HK
565 if No (Decls) then
566 Decls := New_List;
567 Set_Declarations (Unit_Decl, Decls);
568 end if;
569 end if;
570
571 FM_Id := Create_Anonymous_Master (Unit_Id, Decls);
11fa950b 572 end if;
57ae790f
HK
573
574 return FM_Id;
11fa950b 575 end Current_Anonymous_Master;
df3e68b1 576
26bff3d9
JM
577 --------------------------------
578 -- Displace_Allocator_Pointer --
579 --------------------------------
580
581 procedure Displace_Allocator_Pointer (N : Node_Id) is
582 Loc : constant Source_Ptr := Sloc (N);
583 Orig_Node : constant Node_Id := Original_Node (N);
584 Dtyp : Entity_Id;
585 Etyp : Entity_Id;
586 PtrT : Entity_Id;
587
588 begin
303b4d58
AC
589 -- Do nothing in case of VM targets: the virtual machine will handle
590 -- interfaces directly.
591
1f110335 592 if not Tagged_Type_Expansion then
303b4d58
AC
593 return;
594 end if;
595
26bff3d9
JM
596 pragma Assert (Nkind (N) = N_Identifier
597 and then Nkind (Orig_Node) = N_Allocator);
598
599 PtrT := Etype (Orig_Node);
d6a24cdb 600 Dtyp := Available_View (Designated_Type (PtrT));
26bff3d9
JM
601 Etyp := Etype (Expression (Orig_Node));
602
533369aa
AC
603 if Is_Class_Wide_Type (Dtyp) and then Is_Interface (Dtyp) then
604
26bff3d9
JM
605 -- If the type of the allocator expression is not an interface type
606 -- we can generate code to reference the record component containing
607 -- the pointer to the secondary dispatch table.
608
609 if not Is_Interface (Etyp) then
610 declare
611 Saved_Typ : constant Entity_Id := Etype (Orig_Node);
612
613 begin
614 -- 1) Get access to the allocated object
615
616 Rewrite (N,
5972791c 617 Make_Explicit_Dereference (Loc, Relocate_Node (N)));
26bff3d9
JM
618 Set_Etype (N, Etyp);
619 Set_Analyzed (N);
620
621 -- 2) Add the conversion to displace the pointer to reference
622 -- the secondary dispatch table.
623
624 Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
625 Analyze_And_Resolve (N, Dtyp);
626
627 -- 3) The 'access to the secondary dispatch table will be used
628 -- as the value returned by the allocator.
629
630 Rewrite (N,
631 Make_Attribute_Reference (Loc,
632 Prefix => Relocate_Node (N),
633 Attribute_Name => Name_Access));
634 Set_Etype (N, Saved_Typ);
635 Set_Analyzed (N);
636 end;
637
638 -- If the type of the allocator expression is an interface type we
639 -- generate a run-time call to displace "this" to reference the
640 -- component containing the pointer to the secondary dispatch table
641 -- or else raise Constraint_Error if the actual object does not
533369aa 642 -- implement the target interface. This case corresponds to the
26bff3d9
JM
643 -- following example:
644
8fc789c8 645 -- function Op (Obj : Iface_1'Class) return access Iface_2'Class is
26bff3d9
JM
646 -- begin
647 -- return new Iface_2'Class'(Obj);
648 -- end Op;
649
650 else
651 Rewrite (N,
652 Unchecked_Convert_To (PtrT,
653 Make_Function_Call (Loc,
e4494292 654 Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
26bff3d9
JM
655 Parameter_Associations => New_List (
656 Unchecked_Convert_To (RTE (RE_Address),
657 Relocate_Node (N)),
658
659 New_Occurrence_Of
660 (Elists.Node
661 (First_Elmt
662 (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
663 Loc)))));
664 Analyze_And_Resolve (N, PtrT);
665 end if;
666 end if;
667 end Displace_Allocator_Pointer;
668
fbf5a39b
AC
669 ---------------------------------
670 -- Expand_Allocator_Expression --
671 ---------------------------------
672
673 procedure Expand_Allocator_Expression (N : Node_Id) is
f02b8bb8
RD
674 Loc : constant Source_Ptr := Sloc (N);
675 Exp : constant Node_Id := Expression (Expression (N));
f02b8bb8
RD
676 PtrT : constant Entity_Id := Etype (N);
677 DesigT : constant Entity_Id := Designated_Type (PtrT);
26bff3d9
JM
678
679 procedure Apply_Accessibility_Check
680 (Ref : Node_Id;
681 Built_In_Place : Boolean := False);
682 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
685094bf
RD
683 -- type, generate an accessibility check to verify that the level of the
684 -- type of the created object is not deeper than the level of the access
50878404 685 -- type. If the type of the qualified expression is class-wide, then
685094bf
RD
686 -- always generate the check (except in the case where it is known to be
687 -- unnecessary, see comment below). Otherwise, only generate the check
688 -- if the level of the qualified expression type is statically deeper
689 -- than the access type.
690 --
691 -- Although the static accessibility will generally have been performed
692 -- as a legality check, it won't have been done in cases where the
693 -- allocator appears in generic body, so a run-time check is needed in
694 -- general. One special case is when the access type is declared in the
695 -- same scope as the class-wide allocator, in which case the check can
696 -- never fail, so it need not be generated.
697 --
698 -- As an open issue, there seem to be cases where the static level
699 -- associated with the class-wide object's underlying type is not
700 -- sufficient to perform the proper accessibility check, such as for
701 -- allocators in nested subprograms or accept statements initialized by
702 -- class-wide formals when the actual originates outside at a deeper
703 -- static level. The nested subprogram case might require passing
704 -- accessibility levels along with class-wide parameters, and the task
705 -- case seems to be an actual gap in the language rules that needs to
706 -- be fixed by the ARG. ???
26bff3d9
JM
707
708 -------------------------------
709 -- Apply_Accessibility_Check --
710 -------------------------------
711
712 procedure Apply_Accessibility_Check
713 (Ref : Node_Id;
714 Built_In_Place : Boolean := False)
715 is
a98838ff
HK
716 Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT);
717 Cond : Node_Id;
718 Fin_Call : Node_Id;
719 Free_Stmt : Node_Id;
720 Obj_Ref : Node_Id;
721 Stmts : List_Id;
26bff3d9
JM
722
723 begin
0791fbe9 724 if Ada_Version >= Ada_2005
26bff3d9 725 and then Is_Class_Wide_Type (DesigT)
a98838ff 726 and then (Tagged_Type_Expansion or else VM_Target /= No_VM)
3217f71e 727 and then not Scope_Suppress.Suppress (Accessibility_Check)
26bff3d9
JM
728 and then
729 (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
730 or else
731 (Is_Class_Wide_Type (Etype (Exp))
732 and then Scope (PtrT) /= Current_Scope))
733 then
e761d11c 734 -- If the allocator was built in place, Ref is already a reference
26bff3d9 735 -- to the access object initialized to the result of the allocator
e761d11c
AC
736 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
737 -- Remove_Side_Effects for cases where the build-in-place call may
738 -- still be the prefix of the reference (to avoid generating
739 -- duplicate calls). Otherwise, it is the entity associated with
740 -- the object containing the address of the allocated object.
26bff3d9
JM
741
742 if Built_In_Place then
e761d11c 743 Remove_Side_Effects (Ref);
a98838ff 744 Obj_Ref := New_Copy_Tree (Ref);
26bff3d9 745 else
e4494292 746 Obj_Ref := New_Occurrence_Of (Ref, Loc);
50878404
AC
747 end if;
748
b6c8e5be
AC
749 -- For access to interface types we must generate code to displace
750 -- the pointer to the base of the object since the subsequent code
751 -- references components located in the TSD of the object (which
752 -- is associated with the primary dispatch table --see a-tags.ads)
753 -- and also generates code invoking Free, which requires also a
754 -- reference to the base of the unallocated object.
755
cc6f5d75 756 if Is_Interface (DesigT) and then Tagged_Type_Expansion then
b6c8e5be
AC
757 Obj_Ref :=
758 Unchecked_Convert_To (Etype (Obj_Ref),
759 Make_Function_Call (Loc,
662c2ad4
RD
760 Name =>
761 New_Occurrence_Of (RTE (RE_Base_Address), Loc),
b6c8e5be
AC
762 Parameter_Associations => New_List (
763 Unchecked_Convert_To (RTE (RE_Address),
764 New_Copy_Tree (Obj_Ref)))));
765 end if;
766
50878404
AC
767 -- Step 1: Create the object clean up code
768
769 Stmts := New_List;
770
a98838ff
HK
771 -- Deallocate the object if the accessibility check fails. This
772 -- is done only on targets or profiles that support deallocation.
773
774 -- Free (Obj_Ref);
775
776 if RTE_Available (RE_Free) then
777 Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref));
778 Set_Storage_Pool (Free_Stmt, Pool_Id);
779
780 Append_To (Stmts, Free_Stmt);
781
782 -- The target or profile cannot deallocate objects
783
784 else
785 Free_Stmt := Empty;
786 end if;
787
788 -- Finalize the object if applicable. Generate:
a530b8bb
AC
789
790 -- [Deep_]Finalize (Obj_Ref.all);
791
2cbac6c6 792 if Needs_Finalization (DesigT) then
a98838ff 793 Fin_Call :=
cc6f5d75
AC
794 Make_Final_Call
795 (Obj_Ref =>
796 Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
797 Typ => DesigT);
a98838ff
HK
798
799 -- When the target or profile supports deallocation, wrap the
800 -- finalization call in a block to ensure proper deallocation
801 -- even if finalization fails. Generate:
802
803 -- begin
804 -- <Fin_Call>
805 -- exception
806 -- when others =>
807 -- <Free_Stmt>
808 -- raise;
809 -- end;
810
811 if Present (Free_Stmt) then
812 Fin_Call :=
813 Make_Block_Statement (Loc,
814 Handled_Statement_Sequence =>
815 Make_Handled_Sequence_Of_Statements (Loc,
816 Statements => New_List (Fin_Call),
817
818 Exception_Handlers => New_List (
819 Make_Exception_Handler (Loc,
820 Exception_Choices => New_List (
821 Make_Others_Choice (Loc)),
a98838ff
HK
822 Statements => New_List (
823 New_Copy_Tree (Free_Stmt),
824 Make_Raise_Statement (Loc))))));
825 end if;
826
827 Prepend_To (Stmts, Fin_Call);
f46faa08
AC
828 end if;
829
50878404
AC
830 -- Signal the accessibility failure through a Program_Error
831
832 Append_To (Stmts,
833 Make_Raise_Program_Error (Loc,
e4494292 834 Condition => New_Occurrence_Of (Standard_True, Loc),
50878404
AC
835 Reason => PE_Accessibility_Check_Failed));
836
837 -- Step 2: Create the accessibility comparison
838
839 -- Generate:
840 -- Ref'Tag
841
b6c8e5be
AC
842 Obj_Ref :=
843 Make_Attribute_Reference (Loc,
844 Prefix => Obj_Ref,
845 Attribute_Name => Name_Tag);
f46faa08 846
50878404
AC
847 -- For tagged types, determine the accessibility level by looking
848 -- at the type specific data of the dispatch table. Generate:
849
850 -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
851
f46faa08 852 if Tagged_Type_Expansion then
50878404 853 Cond := Build_Get_Access_Level (Loc, Obj_Ref);
f46faa08 854
50878404
AC
855 -- Use a runtime call to determine the accessibility level when
856 -- compiling on virtual machine targets. Generate:
f46faa08 857
50878404 858 -- Get_Access_Level (Ref'Tag)
f46faa08
AC
859
860 else
50878404
AC
861 Cond :=
862 Make_Function_Call (Loc,
863 Name =>
e4494292 864 New_Occurrence_Of (RTE (RE_Get_Access_Level), Loc),
50878404 865 Parameter_Associations => New_List (Obj_Ref));
26bff3d9
JM
866 end if;
867
50878404
AC
868 Cond :=
869 Make_Op_Gt (Loc,
870 Left_Opnd => Cond,
871 Right_Opnd =>
872 Make_Integer_Literal (Loc, Type_Access_Level (PtrT)));
873
874 -- Due to the complexity and side effects of the check, utilize an
875 -- if statement instead of the regular Program_Error circuitry.
876
26bff3d9 877 Insert_Action (N,
8b1011c0 878 Make_Implicit_If_Statement (N,
50878404
AC
879 Condition => Cond,
880 Then_Statements => Stmts));
26bff3d9
JM
881 end if;
882 end Apply_Accessibility_Check;
883
884 -- Local variables
885
df3e68b1
HK
886 Aggr_In_Place : constant Boolean := Is_Delayed_Aggregate (Exp);
887 Indic : constant Node_Id := Subtype_Mark (Expression (N));
888 T : constant Entity_Id := Entity (Indic);
889 Node : Node_Id;
890 Tag_Assign : Node_Id;
891 Temp : Entity_Id;
892 Temp_Decl : Node_Id;
fbf5a39b 893
d26dc4b5
AC
894 TagT : Entity_Id := Empty;
895 -- Type used as source for tag assignment
896
897 TagR : Node_Id := Empty;
898 -- Target reference for tag assignment
899
26bff3d9
JM
900 -- Start of processing for Expand_Allocator_Expression
901
fbf5a39b 902 begin
3bfb3c03
JM
903 -- Handle call to C++ constructor
904
905 if Is_CPP_Constructor_Call (Exp) then
906 Make_CPP_Constructor_Call_In_Allocator
907 (Allocator => N,
908 Function_Call => Exp);
909 return;
910 end if;
911
885c4871 912 -- In the case of an Ada 2012 allocator whose initial value comes from a
63585f75
SB
913 -- function call, pass "the accessibility level determined by the point
914 -- of call" (AI05-0234) to the function. Conceptually, this belongs in
915 -- Expand_Call but it couldn't be done there (because the Etype of the
916 -- allocator wasn't set then) so we generate the parameter here. See
917 -- the Boolean variable Defer in (a block within) Expand_Call.
918
919 if Ada_Version >= Ada_2012 and then Nkind (Exp) = N_Function_Call then
920 declare
921 Subp : Entity_Id;
922
923 begin
924 if Nkind (Name (Exp)) = N_Explicit_Dereference then
925 Subp := Designated_Type (Etype (Prefix (Name (Exp))));
926 else
927 Subp := Entity (Name (Exp));
928 end if;
929
57a3fca9
AC
930 Subp := Ultimate_Alias (Subp);
931
63585f75
SB
932 if Present (Extra_Accessibility_Of_Result (Subp)) then
933 Add_Extra_Actual_To_Call
934 (Subprogram_Call => Exp,
935 Extra_Formal => Extra_Accessibility_Of_Result (Subp),
936 Extra_Actual => Dynamic_Accessibility_Level (PtrT));
937 end if;
938 end;
939 end if;
940
f6194278 941 -- Case of tagged type or type requiring finalization
63585f75
SB
942
943 if Is_Tagged_Type (T) or else Needs_Finalization (T) then
fadcf313 944
685094bf
RD
945 -- Ada 2005 (AI-318-02): If the initialization expression is a call
946 -- to a build-in-place function, then access to the allocated object
947 -- must be passed to the function. Currently we limit such functions
948 -- to those with constrained limited result subtypes, but eventually
949 -- we plan to expand the allowed forms of functions that are treated
950 -- as build-in-place.
20b5d666 951
0791fbe9 952 if Ada_Version >= Ada_2005
20b5d666
JM
953 and then Is_Build_In_Place_Function_Call (Exp)
954 then
955 Make_Build_In_Place_Call_In_Allocator (N, Exp);
26bff3d9
JM
956 Apply_Accessibility_Check (N, Built_In_Place => True);
957 return;
20b5d666
JM
958 end if;
959
ca5af305
AC
960 -- Actions inserted before:
961 -- Temp : constant ptr_T := new T'(Expression);
962 -- Temp._tag = T'tag; -- when not class-wide
963 -- [Deep_]Adjust (Temp.all);
fbf5a39b 964
ca5af305 965 -- We analyze by hand the new internal allocator to avoid any
6b6041ec 966 -- recursion and inappropriate call to Initialize.
7324bf49 967
20b5d666
JM
968 -- We don't want to remove side effects when the expression must be
969 -- built in place. In the case of a build-in-place function call,
970 -- that could lead to a duplication of the call, which was already
971 -- substituted for the allocator.
972
26bff3d9 973 if not Aggr_In_Place then
fbf5a39b
AC
974 Remove_Side_Effects (Exp);
975 end if;
976
e86a3a7e 977 Temp := Make_Temporary (Loc, 'P', N);
fbf5a39b
AC
978
979 -- For a class wide allocation generate the following code:
980
981 -- type Equiv_Record is record ... end record;
982 -- implicit subtype CW is <Class_Wide_Subytpe>;
983 -- temp : PtrT := new CW'(CW!(expr));
984
985 if Is_Class_Wide_Type (T) then
986 Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
987
26bff3d9
JM
988 -- Ada 2005 (AI-251): If the expression is a class-wide interface
989 -- object we generate code to move up "this" to reference the
990 -- base of the object before allocating the new object.
991
992 -- Note that Exp'Address is recursively expanded into a call
993 -- to Base_Address (Exp.Tag)
994
995 if Is_Class_Wide_Type (Etype (Exp))
996 and then Is_Interface (Etype (Exp))
1f110335 997 and then Tagged_Type_Expansion
26bff3d9
JM
998 then
999 Set_Expression
1000 (Expression (N),
1001 Unchecked_Convert_To (Entity (Indic),
1002 Make_Explicit_Dereference (Loc,
1003 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
1004 Make_Attribute_Reference (Loc,
1005 Prefix => Exp,
1006 Attribute_Name => Name_Address)))));
26bff3d9
JM
1007 else
1008 Set_Expression
1009 (Expression (N),
1010 Unchecked_Convert_To (Entity (Indic), Exp));
1011 end if;
fbf5a39b
AC
1012
1013 Analyze_And_Resolve (Expression (N), Entity (Indic));
1014 end if;
1015
df3e68b1 1016 -- Processing for allocators returning non-interface types
fbf5a39b 1017
26bff3d9
JM
1018 if not Is_Interface (Directly_Designated_Type (PtrT)) then
1019 if Aggr_In_Place then
df3e68b1 1020 Temp_Decl :=
26bff3d9
JM
1021 Make_Object_Declaration (Loc,
1022 Defining_Identifier => Temp,
e4494292 1023 Object_Definition => New_Occurrence_Of (PtrT, Loc),
26bff3d9
JM
1024 Expression =>
1025 Make_Allocator (Loc,
df3e68b1 1026 Expression =>
e4494292 1027 New_Occurrence_Of (Etype (Exp), Loc)));
fbf5a39b 1028
fad0600d
AC
1029 -- Copy the Comes_From_Source flag for the allocator we just
1030 -- built, since logically this allocator is a replacement of
1031 -- the original allocator node. This is for proper handling of
1032 -- restriction No_Implicit_Heap_Allocations.
1033
26bff3d9 1034 Set_Comes_From_Source
df3e68b1 1035 (Expression (Temp_Decl), Comes_From_Source (N));
fbf5a39b 1036
df3e68b1
HK
1037 Set_No_Initialization (Expression (Temp_Decl));
1038 Insert_Action (N, Temp_Decl);
fbf5a39b 1039
ca5af305 1040 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 1041 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
fad0600d 1042
d3f70b35 1043 -- Attach the object to the associated finalization master.
deb8dacc
HK
1044 -- This is done manually on .NET/JVM since those compilers do
1045 -- no support pools and can't benefit from internally generated
1046 -- Allocate / Deallocate procedures.
1047
1048 if VM_Target /= No_VM
1049 and then Is_Controlled (DesigT)
d3f70b35 1050 and then Present (Finalization_Master (PtrT))
deb8dacc
HK
1051 then
1052 Insert_Action (N,
cc6f5d75
AC
1053 Make_Attach_Call
1054 (Obj_Ref => New_Occurrence_Of (Temp, Loc),
1055 Ptr_Typ => PtrT));
deb8dacc
HK
1056 end if;
1057
26bff3d9
JM
1058 else
1059 Node := Relocate_Node (N);
1060 Set_Analyzed (Node);
df3e68b1
HK
1061
1062 Temp_Decl :=
26bff3d9
JM
1063 Make_Object_Declaration (Loc,
1064 Defining_Identifier => Temp,
1065 Constant_Present => True,
e4494292 1066 Object_Definition => New_Occurrence_Of (PtrT, Loc),
df3e68b1
HK
1067 Expression => Node);
1068
1069 Insert_Action (N, Temp_Decl);
ca5af305 1070 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
deb8dacc 1071
d3f70b35 1072 -- Attach the object to the associated finalization master.
deb8dacc
HK
1073 -- This is done manually on .NET/JVM since those compilers do
1074 -- no support pools and can't benefit from internally generated
1075 -- Allocate / Deallocate procedures.
1076
1077 if VM_Target /= No_VM
1078 and then Is_Controlled (DesigT)
d3f70b35 1079 and then Present (Finalization_Master (PtrT))
deb8dacc
HK
1080 then
1081 Insert_Action (N,
cc6f5d75
AC
1082 Make_Attach_Call
1083 (Obj_Ref => New_Occurrence_Of (Temp, Loc),
1084 Ptr_Typ => PtrT));
deb8dacc 1085 end if;
fbf5a39b
AC
1086 end if;
1087
26bff3d9
JM
1088 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
1089 -- interface type. In this case we use the type of the qualified
1090 -- expression to allocate the object.
1091
fbf5a39b 1092 else
26bff3d9 1093 declare
191fcb3a 1094 Def_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
26bff3d9 1095 New_Decl : Node_Id;
fbf5a39b 1096
26bff3d9
JM
1097 begin
1098 New_Decl :=
1099 Make_Full_Type_Declaration (Loc,
1100 Defining_Identifier => Def_Id,
cc6f5d75 1101 Type_Definition =>
26bff3d9
JM
1102 Make_Access_To_Object_Definition (Loc,
1103 All_Present => True,
1104 Null_Exclusion_Present => False,
0929eaeb
AC
1105 Constant_Present =>
1106 Is_Access_Constant (Etype (N)),
26bff3d9 1107 Subtype_Indication =>
e4494292 1108 New_Occurrence_Of (Etype (Exp), Loc)));
26bff3d9
JM
1109
1110 Insert_Action (N, New_Decl);
1111
df3e68b1
HK
1112 -- Inherit the allocation-related attributes from the original
1113 -- access type.
26bff3d9 1114
24d4b3d5
AC
1115 Set_Finalization_Master
1116 (Def_Id, Finalization_Master (PtrT));
df3e68b1 1117
24d4b3d5
AC
1118 Set_Associated_Storage_Pool
1119 (Def_Id, Associated_Storage_Pool (PtrT));
758c442c 1120
26bff3d9
JM
1121 -- Declare the object using the previous type declaration
1122
1123 if Aggr_In_Place then
df3e68b1 1124 Temp_Decl :=
26bff3d9
JM
1125 Make_Object_Declaration (Loc,
1126 Defining_Identifier => Temp,
e4494292 1127 Object_Definition => New_Occurrence_Of (Def_Id, Loc),
26bff3d9
JM
1128 Expression =>
1129 Make_Allocator (Loc,
e4494292 1130 New_Occurrence_Of (Etype (Exp), Loc)));
26bff3d9 1131
fad0600d
AC
1132 -- Copy the Comes_From_Source flag for the allocator we just
1133 -- built, since logically this allocator is a replacement of
1134 -- the original allocator node. This is for proper handling
1135 -- of restriction No_Implicit_Heap_Allocations.
1136
26bff3d9 1137 Set_Comes_From_Source
df3e68b1 1138 (Expression (Temp_Decl), Comes_From_Source (N));
26bff3d9 1139
df3e68b1
HK
1140 Set_No_Initialization (Expression (Temp_Decl));
1141 Insert_Action (N, Temp_Decl);
26bff3d9 1142
ca5af305 1143 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 1144 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
26bff3d9 1145
26bff3d9
JM
1146 else
1147 Node := Relocate_Node (N);
1148 Set_Analyzed (Node);
df3e68b1
HK
1149
1150 Temp_Decl :=
26bff3d9
JM
1151 Make_Object_Declaration (Loc,
1152 Defining_Identifier => Temp,
1153 Constant_Present => True,
e4494292 1154 Object_Definition => New_Occurrence_Of (Def_Id, Loc),
df3e68b1
HK
1155 Expression => Node);
1156
1157 Insert_Action (N, Temp_Decl);
ca5af305 1158 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
26bff3d9
JM
1159 end if;
1160
1161 -- Generate an additional object containing the address of the
1162 -- returned object. The type of this second object declaration
685094bf
RD
1163 -- is the correct type required for the common processing that
1164 -- is still performed by this subprogram. The displacement of
1165 -- this pointer to reference the component associated with the
1166 -- interface type will be done at the end of common processing.
26bff3d9
JM
1167
1168 New_Decl :=
1169 Make_Object_Declaration (Loc,
243cae0a 1170 Defining_Identifier => Make_Temporary (Loc, 'P'),
e4494292 1171 Object_Definition => New_Occurrence_Of (PtrT, Loc),
243cae0a 1172 Expression =>
df3e68b1 1173 Unchecked_Convert_To (PtrT,
e4494292 1174 New_Occurrence_Of (Temp, Loc)));
26bff3d9
JM
1175
1176 Insert_Action (N, New_Decl);
1177
df3e68b1
HK
1178 Temp_Decl := New_Decl;
1179 Temp := Defining_Identifier (New_Decl);
26bff3d9 1180 end;
758c442c
GD
1181 end if;
1182
26bff3d9
JM
1183 Apply_Accessibility_Check (Temp);
1184
1185 -- Generate the tag assignment
1186
1187 -- Suppress the tag assignment when VM_Target because VM tags are
1188 -- represented implicitly in objects.
1189
1f110335 1190 if not Tagged_Type_Expansion then
26bff3d9 1191 null;
fbf5a39b 1192
26bff3d9
JM
1193 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
1194 -- interface objects because in this case the tag does not change.
d26dc4b5 1195
26bff3d9
JM
1196 elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
1197 pragma Assert (Is_Class_Wide_Type
1198 (Directly_Designated_Type (Etype (N))));
d26dc4b5
AC
1199 null;
1200
1201 elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
1202 TagT := T;
e4494292 1203 TagR := New_Occurrence_Of (Temp, Loc);
d26dc4b5
AC
1204
1205 elsif Is_Private_Type (T)
1206 and then Is_Tagged_Type (Underlying_Type (T))
fbf5a39b 1207 then
d26dc4b5 1208 TagT := Underlying_Type (T);
dfd99a80
TQ
1209 TagR :=
1210 Unchecked_Convert_To (Underlying_Type (T),
1211 Make_Explicit_Dereference (Loc,
e4494292 1212 Prefix => New_Occurrence_Of (Temp, Loc)));
d26dc4b5
AC
1213 end if;
1214
1215 if Present (TagT) then
38171f43
AC
1216 declare
1217 Full_T : constant Entity_Id := Underlying_Type (TagT);
e4494292 1218
38171f43
AC
1219 begin
1220 Tag_Assign :=
1221 Make_Assignment_Statement (Loc,
cc6f5d75 1222 Name =>
38171f43 1223 Make_Selected_Component (Loc,
cc6f5d75 1224 Prefix => TagR,
38171f43 1225 Selector_Name =>
e4494292
RD
1226 New_Occurrence_Of
1227 (First_Tag_Component (Full_T), Loc)),
1228
38171f43
AC
1229 Expression =>
1230 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 1231 New_Occurrence_Of
38171f43
AC
1232 (Elists.Node
1233 (First_Elmt (Access_Disp_Table (Full_T))), Loc)));
1234 end;
fbf5a39b
AC
1235
1236 -- The previous assignment has to be done in any case
1237
1238 Set_Assignment_OK (Name (Tag_Assign));
1239 Insert_Action (N, Tag_Assign);
fbf5a39b
AC
1240 end if;
1241
533369aa
AC
1242 if Needs_Finalization (DesigT) and then Needs_Finalization (T) then
1243
df3e68b1
HK
1244 -- Generate an Adjust call if the object will be moved. In Ada
1245 -- 2005, the object may be inherently limited, in which case
1246 -- there is no Adjust procedure, and the object is built in
1247 -- place. In Ada 95, the object can be limited but not
1248 -- inherently limited if this allocator came from a return
1249 -- statement (we're allocating the result on the secondary
1250 -- stack). In that case, the object will be moved, so we _do_
1251 -- want to Adjust.
1252
1253 if not Aggr_In_Place
51245e2d 1254 and then not Is_Limited_View (T)
df3e68b1
HK
1255 then
1256 Insert_Action (N,
fbf5a39b 1257
533369aa
AC
1258 -- An unchecked conversion is needed in the classwide case
1259 -- because the designated type can be an ancestor of the
1260 -- subtype mark of the allocator.
fbf5a39b 1261
533369aa
AC
1262 Make_Adjust_Call
1263 (Obj_Ref =>
1264 Unchecked_Convert_To (T,
1265 Make_Explicit_Dereference (Loc,
e4494292 1266 Prefix => New_Occurrence_Of (Temp, Loc))),
533369aa 1267 Typ => T));
df3e68b1 1268 end if;
fbf5a39b
AC
1269 end if;
1270
e4494292 1271 Rewrite (N, New_Occurrence_Of (Temp, Loc));
fbf5a39b
AC
1272 Analyze_And_Resolve (N, PtrT);
1273
685094bf
RD
1274 -- Ada 2005 (AI-251): Displace the pointer to reference the record
1275 -- component containing the secondary dispatch table of the interface
1276 -- type.
26bff3d9
JM
1277
1278 if Is_Interface (Directly_Designated_Type (PtrT)) then
1279 Displace_Allocator_Pointer (N);
1280 end if;
1281
fbf5a39b 1282 elsif Aggr_In_Place then
e86a3a7e 1283 Temp := Make_Temporary (Loc, 'P', N);
df3e68b1 1284 Temp_Decl :=
fbf5a39b
AC
1285 Make_Object_Declaration (Loc,
1286 Defining_Identifier => Temp,
e4494292 1287 Object_Definition => New_Occurrence_Of (PtrT, Loc),
df3e68b1
HK
1288 Expression =>
1289 Make_Allocator (Loc,
e4494292 1290 Expression => New_Occurrence_Of (Etype (Exp), Loc)));
fbf5a39b 1291
fad0600d
AC
1292 -- Copy the Comes_From_Source flag for the allocator we just built,
1293 -- since logically this allocator is a replacement of the original
1294 -- allocator node. This is for proper handling of restriction
1295 -- No_Implicit_Heap_Allocations.
1296
fbf5a39b 1297 Set_Comes_From_Source
df3e68b1
HK
1298 (Expression (Temp_Decl), Comes_From_Source (N));
1299
1300 Set_No_Initialization (Expression (Temp_Decl));
1301 Insert_Action (N, Temp_Decl);
1302
ca5af305 1303 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 1304 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
fbf5a39b 1305
d3f70b35
AC
1306 -- Attach the object to the associated finalization master. Thisis
1307 -- done manually on .NET/JVM since those compilers do no support
deb8dacc
HK
1308 -- pools and cannot benefit from internally generated Allocate and
1309 -- Deallocate procedures.
1310
1311 if VM_Target /= No_VM
1312 and then Is_Controlled (DesigT)
d3f70b35 1313 and then Present (Finalization_Master (PtrT))
deb8dacc
HK
1314 then
1315 Insert_Action (N,
243cae0a 1316 Make_Attach_Call
e4494292 1317 (Obj_Ref => New_Occurrence_Of (Temp, Loc),
243cae0a 1318 Ptr_Typ => PtrT));
deb8dacc
HK
1319 end if;
1320
e4494292 1321 Rewrite (N, New_Occurrence_Of (Temp, Loc));
fbf5a39b
AC
1322 Analyze_And_Resolve (N, PtrT);
1323
533369aa 1324 elsif Is_Access_Type (T) and then Can_Never_Be_Null (T) then
51e4c4b9
AC
1325 Install_Null_Excluding_Check (Exp);
1326
f02b8bb8 1327 elsif Is_Access_Type (DesigT)
fbf5a39b
AC
1328 and then Nkind (Exp) = N_Allocator
1329 and then Nkind (Expression (Exp)) /= N_Qualified_Expression
1330 then
0da2c8ac 1331 -- Apply constraint to designated subtype indication
fbf5a39b 1332
cc6f5d75
AC
1333 Apply_Constraint_Check
1334 (Expression (Exp), Designated_Type (DesigT), No_Sliding => True);
fbf5a39b
AC
1335
1336 if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
1337
1338 -- Propagate constraint_error to enclosing allocator
1339
1340 Rewrite (Exp, New_Copy (Expression (Exp)));
1341 end if;
1df4f514 1342
fbf5a39b 1343 else
14f0f659
AC
1344 Build_Allocate_Deallocate_Proc (N, True);
1345
36c73552
AC
1346 -- If we have:
1347 -- type A is access T1;
1348 -- X : A := new T2'(...);
1349 -- T1 and T2 can be different subtypes, and we might need to check
1350 -- both constraints. First check against the type of the qualified
1351 -- expression.
1352
1353 Apply_Constraint_Check (Exp, T, No_Sliding => True);
fbf5a39b 1354
d79e621a 1355 if Do_Range_Check (Exp) then
d79e621a
GD
1356 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
1357 end if;
1358
685094bf
RD
1359 -- A check is also needed in cases where the designated subtype is
1360 -- constrained and differs from the subtype given in the qualified
1361 -- expression. Note that the check on the qualified expression does
1362 -- not allow sliding, but this check does (a relaxation from Ada 83).
fbf5a39b 1363
f02b8bb8 1364 if Is_Constrained (DesigT)
9450205a 1365 and then not Subtypes_Statically_Match (T, DesigT)
fbf5a39b
AC
1366 then
1367 Apply_Constraint_Check
f02b8bb8 1368 (Exp, DesigT, No_Sliding => False);
d79e621a
GD
1369
1370 if Do_Range_Check (Exp) then
d79e621a
GD
1371 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
1372 end if;
f02b8bb8
RD
1373 end if;
1374
685094bf
RD
1375 -- For an access to unconstrained packed array, GIGI needs to see an
1376 -- expression with a constrained subtype in order to compute the
1377 -- proper size for the allocator.
f02b8bb8
RD
1378
1379 if Is_Array_Type (T)
1380 and then not Is_Constrained (T)
1381 and then Is_Packed (T)
1382 then
1383 declare
191fcb3a 1384 ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
f02b8bb8
RD
1385 Internal_Exp : constant Node_Id := Relocate_Node (Exp);
1386 begin
1387 Insert_Action (Exp,
1388 Make_Subtype_Declaration (Loc,
1389 Defining_Identifier => ConstrT,
25ebc085
AC
1390 Subtype_Indication =>
1391 Make_Subtype_From_Expr (Internal_Exp, T)));
f02b8bb8
RD
1392 Freeze_Itype (ConstrT, Exp);
1393 Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
1394 end;
fbf5a39b 1395 end if;
f02b8bb8 1396
685094bf
RD
1397 -- Ada 2005 (AI-318-02): If the initialization expression is a call
1398 -- to a build-in-place function, then access to the allocated object
1399 -- must be passed to the function. Currently we limit such functions
1400 -- to those with constrained limited result subtypes, but eventually
1401 -- we plan to expand the allowed forms of functions that are treated
1402 -- as build-in-place.
20b5d666 1403
0791fbe9 1404 if Ada_Version >= Ada_2005
20b5d666
JM
1405 and then Is_Build_In_Place_Function_Call (Exp)
1406 then
1407 Make_Build_In_Place_Call_In_Allocator (N, Exp);
1408 end if;
fbf5a39b
AC
1409 end if;
1410
1411 exception
1412 when RE_Not_Available =>
1413 return;
1414 end Expand_Allocator_Expression;
1415
70482933
RK
1416 -----------------------------
1417 -- Expand_Array_Comparison --
1418 -----------------------------
1419
685094bf
RD
1420 -- Expansion is only required in the case of array types. For the unpacked
1421 -- case, an appropriate runtime routine is called. For packed cases, and
1422 -- also in some other cases where a runtime routine cannot be called, the
1423 -- form of the expansion is:
70482933
RK
1424
1425 -- [body for greater_nn; boolean_expression]
1426
1427 -- The body is built by Make_Array_Comparison_Op, and the form of the
1428 -- Boolean expression depends on the operator involved.
1429
1430 procedure Expand_Array_Comparison (N : Node_Id) is
1431 Loc : constant Source_Ptr := Sloc (N);
1432 Op1 : Node_Id := Left_Opnd (N);
1433 Op2 : Node_Id := Right_Opnd (N);
1434 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
fbf5a39b 1435 Ctyp : constant Entity_Id := Component_Type (Typ1);
70482933
RK
1436
1437 Expr : Node_Id;
1438 Func_Body : Node_Id;
1439 Func_Name : Entity_Id;
1440
fbf5a39b
AC
1441 Comp : RE_Id;
1442
9bc43c53
AC
1443 Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
1444 -- True for byte addressable target
91b1417d 1445
fbf5a39b 1446 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
685094bf
RD
1447 -- Returns True if the length of the given operand is known to be less
1448 -- than 4. Returns False if this length is known to be four or greater
1449 -- or is not known at compile time.
fbf5a39b
AC
1450
1451 ------------------------
1452 -- Length_Less_Than_4 --
1453 ------------------------
1454
1455 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
1456 Otyp : constant Entity_Id := Etype (Opnd);
1457
1458 begin
1459 if Ekind (Otyp) = E_String_Literal_Subtype then
1460 return String_Literal_Length (Otyp) < 4;
1461
1462 else
1463 declare
1464 Ityp : constant Entity_Id := Etype (First_Index (Otyp));
1465 Lo : constant Node_Id := Type_Low_Bound (Ityp);
1466 Hi : constant Node_Id := Type_High_Bound (Ityp);
1467 Lov : Uint;
1468 Hiv : Uint;
1469
1470 begin
1471 if Compile_Time_Known_Value (Lo) then
1472 Lov := Expr_Value (Lo);
1473 else
1474 return False;
1475 end if;
1476
1477 if Compile_Time_Known_Value (Hi) then
1478 Hiv := Expr_Value (Hi);
1479 else
1480 return False;
1481 end if;
1482
1483 return Hiv < Lov + 3;
1484 end;
1485 end if;
1486 end Length_Less_Than_4;
1487
1488 -- Start of processing for Expand_Array_Comparison
1489
70482933 1490 begin
fbf5a39b
AC
1491 -- Deal first with unpacked case, where we can call a runtime routine
1492 -- except that we avoid this for targets for which are not addressable
26bff3d9 1493 -- by bytes, and for the JVM/CIL, since they do not support direct
fbf5a39b
AC
1494 -- addressing of array components.
1495
1496 if not Is_Bit_Packed_Array (Typ1)
9bc43c53 1497 and then Byte_Addressable
26bff3d9 1498 and then VM_Target = No_VM
fbf5a39b
AC
1499 then
1500 -- The call we generate is:
1501
1502 -- Compare_Array_xn[_Unaligned]
1503 -- (left'address, right'address, left'length, right'length) <op> 0
1504
1505 -- x = U for unsigned, S for signed
1506 -- n = 8,16,32,64 for component size
1507 -- Add _Unaligned if length < 4 and component size is 8.
1508 -- <op> is the standard comparison operator
1509
1510 if Component_Size (Typ1) = 8 then
1511 if Length_Less_Than_4 (Op1)
1512 or else
1513 Length_Less_Than_4 (Op2)
1514 then
1515 if Is_Unsigned_Type (Ctyp) then
1516 Comp := RE_Compare_Array_U8_Unaligned;
1517 else
1518 Comp := RE_Compare_Array_S8_Unaligned;
1519 end if;
1520
1521 else
1522 if Is_Unsigned_Type (Ctyp) then
1523 Comp := RE_Compare_Array_U8;
1524 else
1525 Comp := RE_Compare_Array_S8;
1526 end if;
1527 end if;
1528
1529 elsif Component_Size (Typ1) = 16 then
1530 if Is_Unsigned_Type (Ctyp) then
1531 Comp := RE_Compare_Array_U16;
1532 else
1533 Comp := RE_Compare_Array_S16;
1534 end if;
1535
1536 elsif Component_Size (Typ1) = 32 then
1537 if Is_Unsigned_Type (Ctyp) then
1538 Comp := RE_Compare_Array_U32;
1539 else
1540 Comp := RE_Compare_Array_S32;
1541 end if;
1542
1543 else pragma Assert (Component_Size (Typ1) = 64);
1544 if Is_Unsigned_Type (Ctyp) then
1545 Comp := RE_Compare_Array_U64;
1546 else
1547 Comp := RE_Compare_Array_S64;
1548 end if;
1549 end if;
1550
1551 Remove_Side_Effects (Op1, Name_Req => True);
1552 Remove_Side_Effects (Op2, Name_Req => True);
1553
1554 Rewrite (Op1,
1555 Make_Function_Call (Sloc (Op1),
1556 Name => New_Occurrence_Of (RTE (Comp), Loc),
1557
1558 Parameter_Associations => New_List (
1559 Make_Attribute_Reference (Loc,
1560 Prefix => Relocate_Node (Op1),
1561 Attribute_Name => Name_Address),
1562
1563 Make_Attribute_Reference (Loc,
1564 Prefix => Relocate_Node (Op2),
1565 Attribute_Name => Name_Address),
1566
1567 Make_Attribute_Reference (Loc,
1568 Prefix => Relocate_Node (Op1),
1569 Attribute_Name => Name_Length),
1570
1571 Make_Attribute_Reference (Loc,
1572 Prefix => Relocate_Node (Op2),
1573 Attribute_Name => Name_Length))));
1574
1575 Rewrite (Op2,
1576 Make_Integer_Literal (Sloc (Op2),
1577 Intval => Uint_0));
1578
1579 Analyze_And_Resolve (Op1, Standard_Integer);
1580 Analyze_And_Resolve (Op2, Standard_Integer);
1581 return;
1582 end if;
1583
1584 -- Cases where we cannot make runtime call
1585
70482933
RK
1586 -- For (a <= b) we convert to not (a > b)
1587
1588 if Chars (N) = Name_Op_Le then
1589 Rewrite (N,
1590 Make_Op_Not (Loc,
1591 Right_Opnd =>
1592 Make_Op_Gt (Loc,
1593 Left_Opnd => Op1,
1594 Right_Opnd => Op2)));
1595 Analyze_And_Resolve (N, Standard_Boolean);
1596 return;
1597
1598 -- For < the Boolean expression is
1599 -- greater__nn (op2, op1)
1600
1601 elsif Chars (N) = Name_Op_Lt then
1602 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1603
1604 -- Switch operands
1605
1606 Op1 := Right_Opnd (N);
1607 Op2 := Left_Opnd (N);
1608
1609 -- For (a >= b) we convert to not (a < b)
1610
1611 elsif Chars (N) = Name_Op_Ge then
1612 Rewrite (N,
1613 Make_Op_Not (Loc,
1614 Right_Opnd =>
1615 Make_Op_Lt (Loc,
1616 Left_Opnd => Op1,
1617 Right_Opnd => Op2)));
1618 Analyze_And_Resolve (N, Standard_Boolean);
1619 return;
1620
1621 -- For > the Boolean expression is
1622 -- greater__nn (op1, op2)
1623
1624 else
1625 pragma Assert (Chars (N) = Name_Op_Gt);
1626 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1627 end if;
1628
1629 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1630 Expr :=
1631 Make_Function_Call (Loc,
e4494292 1632 Name => New_Occurrence_Of (Func_Name, Loc),
70482933
RK
1633 Parameter_Associations => New_List (Op1, Op2));
1634
1635 Insert_Action (N, Func_Body);
1636 Rewrite (N, Expr);
1637 Analyze_And_Resolve (N, Standard_Boolean);
1638
fbf5a39b
AC
1639 exception
1640 when RE_Not_Available =>
1641 return;
70482933
RK
1642 end Expand_Array_Comparison;
1643
1644 ---------------------------
1645 -- Expand_Array_Equality --
1646 ---------------------------
1647
685094bf
RD
1648 -- Expand an equality function for multi-dimensional arrays. Here is an
1649 -- example of such a function for Nb_Dimension = 2
70482933 1650
0da2c8ac 1651 -- function Enn (A : atyp; B : btyp) return boolean is
70482933 1652 -- begin
fbf5a39b
AC
1653 -- if (A'length (1) = 0 or else A'length (2) = 0)
1654 -- and then
1655 -- (B'length (1) = 0 or else B'length (2) = 0)
1656 -- then
1657 -- return True; -- RM 4.5.2(22)
1658 -- end if;
0da2c8ac 1659
fbf5a39b
AC
1660 -- if A'length (1) /= B'length (1)
1661 -- or else
1662 -- A'length (2) /= B'length (2)
1663 -- then
1664 -- return False; -- RM 4.5.2(23)
1665 -- end if;
0da2c8ac 1666
fbf5a39b 1667 -- declare
523456db
AC
1668 -- A1 : Index_T1 := A'first (1);
1669 -- B1 : Index_T1 := B'first (1);
fbf5a39b 1670 -- begin
523456db 1671 -- loop
fbf5a39b 1672 -- declare
523456db
AC
1673 -- A2 : Index_T2 := A'first (2);
1674 -- B2 : Index_T2 := B'first (2);
fbf5a39b 1675 -- begin
523456db 1676 -- loop
fbf5a39b
AC
1677 -- if A (A1, A2) /= B (B1, B2) then
1678 -- return False;
70482933 1679 -- end if;
0da2c8ac 1680
523456db
AC
1681 -- exit when A2 = A'last (2);
1682 -- A2 := Index_T2'succ (A2);
0da2c8ac 1683 -- B2 := Index_T2'succ (B2);
70482933 1684 -- end loop;
fbf5a39b 1685 -- end;
0da2c8ac 1686
523456db
AC
1687 -- exit when A1 = A'last (1);
1688 -- A1 := Index_T1'succ (A1);
0da2c8ac 1689 -- B1 := Index_T1'succ (B1);
70482933 1690 -- end loop;
fbf5a39b 1691 -- end;
0da2c8ac 1692
70482933
RK
1693 -- return true;
1694 -- end Enn;
1695
685094bf
RD
1696 -- Note on the formal types used (atyp and btyp). If either of the arrays
1697 -- is of a private type, we use the underlying type, and do an unchecked
1698 -- conversion of the actual. If either of the arrays has a bound depending
1699 -- on a discriminant, then we use the base type since otherwise we have an
1700 -- escaped discriminant in the function.
0da2c8ac 1701
685094bf
RD
1702 -- If both arrays are constrained and have the same bounds, we can generate
1703 -- a loop with an explicit iteration scheme using a 'Range attribute over
1704 -- the first array.
523456db 1705
70482933
RK
1706 function Expand_Array_Equality
1707 (Nod : Node_Id;
70482933
RK
1708 Lhs : Node_Id;
1709 Rhs : Node_Id;
0da2c8ac
AC
1710 Bodies : List_Id;
1711 Typ : Entity_Id) return Node_Id
70482933
RK
1712 is
1713 Loc : constant Source_Ptr := Sloc (Nod);
fbf5a39b
AC
1714 Decls : constant List_Id := New_List;
1715 Index_List1 : constant List_Id := New_List;
1716 Index_List2 : constant List_Id := New_List;
1717
1718 Actuals : List_Id;
1719 Formals : List_Id;
1720 Func_Name : Entity_Id;
1721 Func_Body : Node_Id;
70482933
RK
1722
1723 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
1724 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
1725
0da2c8ac
AC
1726 Ltyp : Entity_Id;
1727 Rtyp : Entity_Id;
1728 -- The parameter types to be used for the formals
1729
fbf5a39b
AC
1730 function Arr_Attr
1731 (Arr : Entity_Id;
1732 Nam : Name_Id;
2e071734 1733 Num : Int) return Node_Id;
5e1c00fa 1734 -- This builds the attribute reference Arr'Nam (Expr)
fbf5a39b 1735
70482933 1736 function Component_Equality (Typ : Entity_Id) return Node_Id;
685094bf 1737 -- Create one statement to compare corresponding components, designated
3b42c566 1738 -- by a full set of indexes.
70482933 1739
0da2c8ac 1740 function Get_Arg_Type (N : Node_Id) return Entity_Id;
685094bf
RD
1741 -- Given one of the arguments, computes the appropriate type to be used
1742 -- for that argument in the corresponding function formal
0da2c8ac 1743
fbf5a39b 1744 function Handle_One_Dimension
70482933 1745 (N : Int;
2e071734 1746 Index : Node_Id) return Node_Id;
0da2c8ac 1747 -- This procedure returns the following code
fbf5a39b
AC
1748 --
1749 -- declare
523456db 1750 -- Bn : Index_T := B'First (N);
fbf5a39b 1751 -- begin
523456db 1752 -- loop
fbf5a39b 1753 -- xxx
523456db
AC
1754 -- exit when An = A'Last (N);
1755 -- An := Index_T'Succ (An)
0da2c8ac 1756 -- Bn := Index_T'Succ (Bn)
fbf5a39b
AC
1757 -- end loop;
1758 -- end;
1759 --
3b42c566 1760 -- If both indexes are constrained and identical, the procedure
523456db
AC
1761 -- returns a simpler loop:
1762 --
1763 -- for An in A'Range (N) loop
1764 -- xxx
1765 -- end loop
0da2c8ac 1766 --
523456db 1767 -- N is the dimension for which we are generating a loop. Index is the
685094bf
RD
1768 -- N'th index node, whose Etype is Index_Type_n in the above code. The
1769 -- xxx statement is either the loop or declare for the next dimension
1770 -- or if this is the last dimension the comparison of corresponding
1771 -- components of the arrays.
fbf5a39b 1772 --
685094bf 1773 -- The actual way the code works is to return the comparison of
a90bd866 1774 -- corresponding components for the N+1 call. That's neater.
fbf5a39b
AC
1775
1776 function Test_Empty_Arrays return Node_Id;
1777 -- This function constructs the test for both arrays being empty
1778 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1779 -- and then
1780 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1781
1782 function Test_Lengths_Correspond return Node_Id;
685094bf
RD
1783 -- This function constructs the test for arrays having different lengths
1784 -- in at least one index position, in which case the resulting code is:
fbf5a39b
AC
1785
1786 -- A'length (1) /= B'length (1)
1787 -- or else
1788 -- A'length (2) /= B'length (2)
1789 -- or else
1790 -- ...
1791
1792 --------------
1793 -- Arr_Attr --
1794 --------------
1795
1796 function Arr_Attr
1797 (Arr : Entity_Id;
1798 Nam : Name_Id;
2e071734 1799 Num : Int) return Node_Id
fbf5a39b
AC
1800 is
1801 begin
1802 return
1803 Make_Attribute_Reference (Loc,
cc6f5d75
AC
1804 Attribute_Name => Nam,
1805 Prefix => New_Occurrence_Of (Arr, Loc),
1806 Expressions => New_List (Make_Integer_Literal (Loc, Num)));
fbf5a39b 1807 end Arr_Attr;
70482933
RK
1808
1809 ------------------------
1810 -- Component_Equality --
1811 ------------------------
1812
1813 function Component_Equality (Typ : Entity_Id) return Node_Id is
1814 Test : Node_Id;
1815 L, R : Node_Id;
1816
1817 begin
1818 -- if a(i1...) /= b(j1...) then return false; end if;
1819
1820 L :=
1821 Make_Indexed_Component (Loc,
7675ad4f 1822 Prefix => Make_Identifier (Loc, Chars (A)),
70482933
RK
1823 Expressions => Index_List1);
1824
1825 R :=
1826 Make_Indexed_Component (Loc,
7675ad4f 1827 Prefix => Make_Identifier (Loc, Chars (B)),
70482933
RK
1828 Expressions => Index_List2);
1829
1830 Test := Expand_Composite_Equality
1831 (Nod, Component_Type (Typ), L, R, Decls);
1832
a9d8907c
JM
1833 -- If some (sub)component is an unchecked_union, the whole operation
1834 -- will raise program error.
8aceda64
AC
1835
1836 if Nkind (Test) = N_Raise_Program_Error then
a9d8907c
JM
1837
1838 -- This node is going to be inserted at a location where a
685094bf
RD
1839 -- statement is expected: clear its Etype so analysis will set
1840 -- it to the expected Standard_Void_Type.
a9d8907c
JM
1841
1842 Set_Etype (Test, Empty);
8aceda64
AC
1843 return Test;
1844
1845 else
1846 return
1847 Make_Implicit_If_Statement (Nod,
cc6f5d75 1848 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
8aceda64 1849 Then_Statements => New_List (
d766cee3 1850 Make_Simple_Return_Statement (Loc,
8aceda64
AC
1851 Expression => New_Occurrence_Of (Standard_False, Loc))));
1852 end if;
70482933
RK
1853 end Component_Equality;
1854
0da2c8ac
AC
1855 ------------------
1856 -- Get_Arg_Type --
1857 ------------------
1858
1859 function Get_Arg_Type (N : Node_Id) return Entity_Id is
1860 T : Entity_Id;
1861 X : Node_Id;
1862
1863 begin
1864 T := Etype (N);
1865
1866 if No (T) then
1867 return Typ;
1868
1869 else
1870 T := Underlying_Type (T);
1871
1872 X := First_Index (T);
1873 while Present (X) loop
761f7dcb
AC
1874 if Denotes_Discriminant (Type_Low_Bound (Etype (X)))
1875 or else
1876 Denotes_Discriminant (Type_High_Bound (Etype (X)))
0da2c8ac
AC
1877 then
1878 T := Base_Type (T);
1879 exit;
1880 end if;
1881
1882 Next_Index (X);
1883 end loop;
1884
1885 return T;
1886 end if;
1887 end Get_Arg_Type;
1888
fbf5a39b
AC
1889 --------------------------
1890 -- Handle_One_Dimension --
1891 ---------------------------
70482933 1892
fbf5a39b 1893 function Handle_One_Dimension
70482933 1894 (N : Int;
2e071734 1895 Index : Node_Id) return Node_Id
70482933 1896 is
0da2c8ac 1897 Need_Separate_Indexes : constant Boolean :=
761f7dcb 1898 Ltyp /= Rtyp or else not Is_Constrained (Ltyp);
0da2c8ac 1899 -- If the index types are identical, and we are working with
685094bf
RD
1900 -- constrained types, then we can use the same index for both
1901 -- of the arrays.
0da2c8ac 1902
191fcb3a 1903 An : constant Entity_Id := Make_Temporary (Loc, 'A');
0da2c8ac
AC
1904
1905 Bn : Entity_Id;
1906 Index_T : Entity_Id;
1907 Stm_List : List_Id;
1908 Loop_Stm : Node_Id;
70482933
RK
1909
1910 begin
0da2c8ac
AC
1911 if N > Number_Dimensions (Ltyp) then
1912 return Component_Equality (Ltyp);
fbf5a39b 1913 end if;
70482933 1914
0da2c8ac
AC
1915 -- Case where we generate a loop
1916
1917 Index_T := Base_Type (Etype (Index));
1918
1919 if Need_Separate_Indexes then
191fcb3a 1920 Bn := Make_Temporary (Loc, 'B');
0da2c8ac
AC
1921 else
1922 Bn := An;
1923 end if;
70482933 1924
e4494292
RD
1925 Append (New_Occurrence_Of (An, Loc), Index_List1);
1926 Append (New_Occurrence_Of (Bn, Loc), Index_List2);
70482933 1927
0da2c8ac
AC
1928 Stm_List := New_List (
1929 Handle_One_Dimension (N + 1, Next_Index (Index)));
70482933 1930
0da2c8ac 1931 if Need_Separate_Indexes then
a9d8907c 1932
3b42c566 1933 -- Generate guard for loop, followed by increments of indexes
523456db
AC
1934
1935 Append_To (Stm_List,
1936 Make_Exit_Statement (Loc,
1937 Condition =>
1938 Make_Op_Eq (Loc,
cc6f5d75 1939 Left_Opnd => New_Occurrence_Of (An, Loc),
523456db
AC
1940 Right_Opnd => Arr_Attr (A, Name_Last, N))));
1941
1942 Append_To (Stm_List,
1943 Make_Assignment_Statement (Loc,
e4494292 1944 Name => New_Occurrence_Of (An, Loc),
523456db
AC
1945 Expression =>
1946 Make_Attribute_Reference (Loc,
e4494292 1947 Prefix => New_Occurrence_Of (Index_T, Loc),
523456db 1948 Attribute_Name => Name_Succ,
e4494292
RD
1949 Expressions => New_List (
1950 New_Occurrence_Of (An, Loc)))));
523456db 1951
0da2c8ac
AC
1952 Append_To (Stm_List,
1953 Make_Assignment_Statement (Loc,
e4494292 1954 Name => New_Occurrence_Of (Bn, Loc),
0da2c8ac
AC
1955 Expression =>
1956 Make_Attribute_Reference (Loc,
e4494292 1957 Prefix => New_Occurrence_Of (Index_T, Loc),
0da2c8ac 1958 Attribute_Name => Name_Succ,
e4494292
RD
1959 Expressions => New_List (
1960 New_Occurrence_Of (Bn, Loc)))));
0da2c8ac
AC
1961 end if;
1962
a9d8907c
JM
1963 -- If separate indexes, we need a declare block for An and Bn, and a
1964 -- loop without an iteration scheme.
0da2c8ac
AC
1965
1966 if Need_Separate_Indexes then
523456db
AC
1967 Loop_Stm :=
1968 Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);
1969
0da2c8ac
AC
1970 return
1971 Make_Block_Statement (Loc,
1972 Declarations => New_List (
523456db
AC
1973 Make_Object_Declaration (Loc,
1974 Defining_Identifier => An,
e4494292 1975 Object_Definition => New_Occurrence_Of (Index_T, Loc),
523456db
AC
1976 Expression => Arr_Attr (A, Name_First, N)),
1977
0da2c8ac
AC
1978 Make_Object_Declaration (Loc,
1979 Defining_Identifier => Bn,
e4494292 1980 Object_Definition => New_Occurrence_Of (Index_T, Loc),
0da2c8ac 1981 Expression => Arr_Attr (B, Name_First, N))),
523456db 1982
0da2c8ac
AC
1983 Handled_Statement_Sequence =>
1984 Make_Handled_Sequence_Of_Statements (Loc,
1985 Statements => New_List (Loop_Stm)));
1986
523456db
AC
1987 -- If no separate indexes, return loop statement with explicit
1988 -- iteration scheme on its own
0da2c8ac
AC
1989
1990 else
523456db
AC
1991 Loop_Stm :=
1992 Make_Implicit_Loop_Statement (Nod,
1993 Statements => Stm_List,
1994 Iteration_Scheme =>
1995 Make_Iteration_Scheme (Loc,
1996 Loop_Parameter_Specification =>
1997 Make_Loop_Parameter_Specification (Loc,
1998 Defining_Identifier => An,
1999 Discrete_Subtype_Definition =>
2000 Arr_Attr (A, Name_Range, N))));
0da2c8ac
AC
2001 return Loop_Stm;
2002 end if;
fbf5a39b
AC
2003 end Handle_One_Dimension;
2004
2005 -----------------------
2006 -- Test_Empty_Arrays --
2007 -----------------------
2008
2009 function Test_Empty_Arrays return Node_Id is
2010 Alist : Node_Id;
2011 Blist : Node_Id;
2012
2013 Atest : Node_Id;
2014 Btest : Node_Id;
70482933 2015
fbf5a39b
AC
2016 begin
2017 Alist := Empty;
2018 Blist := Empty;
0da2c8ac 2019 for J in 1 .. Number_Dimensions (Ltyp) loop
fbf5a39b
AC
2020 Atest :=
2021 Make_Op_Eq (Loc,
2022 Left_Opnd => Arr_Attr (A, Name_Length, J),
2023 Right_Opnd => Make_Integer_Literal (Loc, 0));
2024
2025 Btest :=
2026 Make_Op_Eq (Loc,
2027 Left_Opnd => Arr_Attr (B, Name_Length, J),
2028 Right_Opnd => Make_Integer_Literal (Loc, 0));
2029
2030 if No (Alist) then
2031 Alist := Atest;
2032 Blist := Btest;
70482933 2033
fbf5a39b
AC
2034 else
2035 Alist :=
2036 Make_Or_Else (Loc,
2037 Left_Opnd => Relocate_Node (Alist),
2038 Right_Opnd => Atest);
2039
2040 Blist :=
2041 Make_Or_Else (Loc,
2042 Left_Opnd => Relocate_Node (Blist),
2043 Right_Opnd => Btest);
2044 end if;
2045 end loop;
70482933 2046
fbf5a39b
AC
2047 return
2048 Make_And_Then (Loc,
2049 Left_Opnd => Alist,
2050 Right_Opnd => Blist);
2051 end Test_Empty_Arrays;
70482933 2052
fbf5a39b
AC
2053 -----------------------------
2054 -- Test_Lengths_Correspond --
2055 -----------------------------
70482933 2056
fbf5a39b
AC
2057 function Test_Lengths_Correspond return Node_Id is
2058 Result : Node_Id;
2059 Rtest : Node_Id;
2060
2061 begin
2062 Result := Empty;
0da2c8ac 2063 for J in 1 .. Number_Dimensions (Ltyp) loop
fbf5a39b
AC
2064 Rtest :=
2065 Make_Op_Ne (Loc,
2066 Left_Opnd => Arr_Attr (A, Name_Length, J),
2067 Right_Opnd => Arr_Attr (B, Name_Length, J));
2068
2069 if No (Result) then
2070 Result := Rtest;
2071 else
2072 Result :=
2073 Make_Or_Else (Loc,
2074 Left_Opnd => Relocate_Node (Result),
2075 Right_Opnd => Rtest);
2076 end if;
2077 end loop;
2078
2079 return Result;
2080 end Test_Lengths_Correspond;
70482933
RK
2081
2082 -- Start of processing for Expand_Array_Equality
2083
2084 begin
0da2c8ac
AC
2085 Ltyp := Get_Arg_Type (Lhs);
2086 Rtyp := Get_Arg_Type (Rhs);
2087
685094bf
RD
2088 -- For now, if the argument types are not the same, go to the base type,
2089 -- since the code assumes that the formals have the same type. This is
2090 -- fixable in future ???
0da2c8ac
AC
2091
2092 if Ltyp /= Rtyp then
2093 Ltyp := Base_Type (Ltyp);
2094 Rtyp := Base_Type (Rtyp);
2095 pragma Assert (Ltyp = Rtyp);
2096 end if;
2097
2098 -- Build list of formals for function
2099
70482933
RK
2100 Formals := New_List (
2101 Make_Parameter_Specification (Loc,
2102 Defining_Identifier => A,
e4494292 2103 Parameter_Type => New_Occurrence_Of (Ltyp, Loc)),
70482933
RK
2104
2105 Make_Parameter_Specification (Loc,
2106 Defining_Identifier => B,
e4494292 2107 Parameter_Type => New_Occurrence_Of (Rtyp, Loc)));
70482933 2108
191fcb3a 2109 Func_Name := Make_Temporary (Loc, 'E');
70482933 2110
fbf5a39b 2111 -- Build statement sequence for function
70482933
RK
2112
2113 Func_Body :=
2114 Make_Subprogram_Body (Loc,
2115 Specification =>
2116 Make_Function_Specification (Loc,
2117 Defining_Unit_Name => Func_Name,
2118 Parameter_Specifications => Formals,
e4494292 2119 Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),
fbf5a39b
AC
2120
2121 Declarations => Decls,
2122
70482933
RK
2123 Handled_Statement_Sequence =>
2124 Make_Handled_Sequence_Of_Statements (Loc,
2125 Statements => New_List (
fbf5a39b
AC
2126
2127 Make_Implicit_If_Statement (Nod,
cc6f5d75 2128 Condition => Test_Empty_Arrays,
fbf5a39b 2129 Then_Statements => New_List (
d766cee3 2130 Make_Simple_Return_Statement (Loc,
fbf5a39b
AC
2131 Expression =>
2132 New_Occurrence_Of (Standard_True, Loc)))),
2133
2134 Make_Implicit_If_Statement (Nod,
cc6f5d75 2135 Condition => Test_Lengths_Correspond,
fbf5a39b 2136 Then_Statements => New_List (
d766cee3 2137 Make_Simple_Return_Statement (Loc,
cc6f5d75 2138 Expression => New_Occurrence_Of (Standard_False, Loc)))),
fbf5a39b 2139
0da2c8ac 2140 Handle_One_Dimension (1, First_Index (Ltyp)),
fbf5a39b 2141
d766cee3 2142 Make_Simple_Return_Statement (Loc,
70482933
RK
2143 Expression => New_Occurrence_Of (Standard_True, Loc)))));
2144
2145 Set_Has_Completion (Func_Name, True);
0da2c8ac 2146 Set_Is_Inlined (Func_Name);
70482933 2147
685094bf
RD
2148 -- If the array type is distinct from the type of the arguments, it
2149 -- is the full view of a private type. Apply an unchecked conversion
2150 -- to insure that analysis of the call succeeds.
70482933 2151
0da2c8ac
AC
2152 declare
2153 L, R : Node_Id;
2154
2155 begin
2156 L := Lhs;
2157 R := Rhs;
2158
2159 if No (Etype (Lhs))
2160 or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
2161 then
2162 L := OK_Convert_To (Ltyp, Lhs);
2163 end if;
2164
2165 if No (Etype (Rhs))
2166 or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
2167 then
2168 R := OK_Convert_To (Rtyp, Rhs);
2169 end if;
2170
2171 Actuals := New_List (L, R);
2172 end;
70482933
RK
2173
2174 Append_To (Bodies, Func_Body);
2175
2176 return
2177 Make_Function_Call (Loc,
e4494292 2178 Name => New_Occurrence_Of (Func_Name, Loc),
70482933
RK
2179 Parameter_Associations => Actuals);
2180 end Expand_Array_Equality;
2181
2182 -----------------------------
2183 -- Expand_Boolean_Operator --
2184 -----------------------------
2185
685094bf
RD
2186 -- Note that we first get the actual subtypes of the operands, since we
2187 -- always want to deal with types that have bounds.
70482933
RK
2188
2189 procedure Expand_Boolean_Operator (N : Node_Id) is
fbf5a39b 2190 Typ : constant Entity_Id := Etype (N);
70482933
RK
2191
2192 begin
685094bf
RD
2193 -- Special case of bit packed array where both operands are known to be
2194 -- properly aligned. In this case we use an efficient run time routine
2195 -- to carry out the operation (see System.Bit_Ops).
a9d8907c
JM
2196
2197 if Is_Bit_Packed_Array (Typ)
2198 and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
2199 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
2200 then
70482933 2201 Expand_Packed_Boolean_Operator (N);
a9d8907c
JM
2202 return;
2203 end if;
70482933 2204
a9d8907c
JM
2205 -- For the normal non-packed case, the general expansion is to build
2206 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
2207 -- and then inserting it into the tree. The original operator node is
2208 -- then rewritten as a call to this function. We also use this in the
2209 -- packed case if either operand is a possibly unaligned object.
70482933 2210
a9d8907c
JM
2211 declare
2212 Loc : constant Source_Ptr := Sloc (N);
2213 L : constant Node_Id := Relocate_Node (Left_Opnd (N));
2214 R : constant Node_Id := Relocate_Node (Right_Opnd (N));
2215 Func_Body : Node_Id;
2216 Func_Name : Entity_Id;
fbf5a39b 2217
a9d8907c
JM
2218 begin
2219 Convert_To_Actual_Subtype (L);
2220 Convert_To_Actual_Subtype (R);
2221 Ensure_Defined (Etype (L), N);
2222 Ensure_Defined (Etype (R), N);
2223 Apply_Length_Check (R, Etype (L));
2224
b4592168
GD
2225 if Nkind (N) = N_Op_Xor then
2226 Silly_Boolean_Array_Xor_Test (N, Etype (L));
2227 end if;
2228
a9d8907c
JM
2229 if Nkind (Parent (N)) = N_Assignment_Statement
2230 and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
2231 then
2232 Build_Boolean_Array_Proc_Call (Parent (N), L, R);
fbf5a39b 2233
a9d8907c
JM
2234 elsif Nkind (Parent (N)) = N_Op_Not
2235 and then Nkind (N) = N_Op_And
39f0fa29 2236 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
cc6f5d75 2237 and then Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
a9d8907c
JM
2238 then
2239 return;
2240 else
fbf5a39b 2241
a9d8907c
JM
2242 Func_Body := Make_Boolean_Array_Op (Etype (L), N);
2243 Func_Name := Defining_Unit_Name (Specification (Func_Body));
2244 Insert_Action (N, Func_Body);
70482933 2245
a9d8907c 2246 -- Now rewrite the expression with a call
70482933 2247
a9d8907c
JM
2248 Rewrite (N,
2249 Make_Function_Call (Loc,
e4494292 2250 Name => New_Occurrence_Of (Func_Name, Loc),
a9d8907c
JM
2251 Parameter_Associations =>
2252 New_List (
2253 L,
2254 Make_Type_Conversion
e4494292 2255 (Loc, New_Occurrence_Of (Etype (L), Loc), R))));
70482933 2256
a9d8907c
JM
2257 Analyze_And_Resolve (N, Typ);
2258 end if;
2259 end;
70482933
RK
2260 end Expand_Boolean_Operator;
2261
456cbfa5
AC
2262 ------------------------------------------------
2263 -- Expand_Compare_Minimize_Eliminate_Overflow --
2264 ------------------------------------------------
2265
2266 procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id) is
2267 Loc : constant Source_Ptr := Sloc (N);
2268
71fb4dc8
AC
2269 Result_Type : constant Entity_Id := Etype (N);
2270 -- Capture result type (could be a derived boolean type)
2271
456cbfa5
AC
2272 Llo, Lhi : Uint;
2273 Rlo, Rhi : Uint;
2274
2275 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
2276 -- Entity for Long_Long_Integer'Base
2277
15c94a55 2278 Check : constant Overflow_Mode_Type := Overflow_Check_Mode;
a7f1b24f 2279 -- Current overflow checking mode
456cbfa5
AC
2280
2281 procedure Set_True;
2282 procedure Set_False;
2283 -- These procedures rewrite N with an occurrence of Standard_True or
2284 -- Standard_False, and then makes a call to Warn_On_Known_Condition.
2285
2286 ---------------
2287 -- Set_False --
2288 ---------------
2289
2290 procedure Set_False is
2291 begin
2292 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
2293 Warn_On_Known_Condition (N);
2294 end Set_False;
2295
2296 --------------
2297 -- Set_True --
2298 --------------
2299
2300 procedure Set_True is
2301 begin
2302 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
2303 Warn_On_Known_Condition (N);
2304 end Set_True;
2305
2306 -- Start of processing for Expand_Compare_Minimize_Eliminate_Overflow
2307
2308 begin
2309 -- Nothing to do unless we have a comparison operator with operands
2310 -- that are signed integer types, and we are operating in either
2311 -- MINIMIZED or ELIMINATED overflow checking mode.
2312
2313 if Nkind (N) not in N_Op_Compare
2314 or else Check not in Minimized_Or_Eliminated
2315 or else not Is_Signed_Integer_Type (Etype (Left_Opnd (N)))
2316 then
2317 return;
2318 end if;
2319
2320 -- OK, this is the case we are interested in. First step is to process
2321 -- our operands using the Minimize_Eliminate circuitry which applies
2322 -- this processing to the two operand subtrees.
2323
a7f1b24f 2324 Minimize_Eliminate_Overflows
c7e152b5 2325 (Left_Opnd (N), Llo, Lhi, Top_Level => False);
a7f1b24f 2326 Minimize_Eliminate_Overflows
c7e152b5 2327 (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
456cbfa5 2328
65f7ed64
AC
2329 -- See if the range information decides the result of the comparison.
2330 -- We can only do this if we in fact have full range information (which
2331 -- won't be the case if either operand is bignum at this stage).
456cbfa5 2332
65f7ed64
AC
2333 if Llo /= No_Uint and then Rlo /= No_Uint then
2334 case N_Op_Compare (Nkind (N)) is
456cbfa5
AC
2335 when N_Op_Eq =>
2336 if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
2337 Set_True;
a40ada7e 2338 elsif Llo > Rhi or else Lhi < Rlo then
456cbfa5
AC
2339 Set_False;
2340 end if;
2341
2342 when N_Op_Ge =>
2343 if Llo >= Rhi then
2344 Set_True;
2345 elsif Lhi < Rlo then
2346 Set_False;
2347 end if;
2348
2349 when N_Op_Gt =>
2350 if Llo > Rhi then
2351 Set_True;
2352 elsif Lhi <= Rlo then
2353 Set_False;
2354 end if;
2355
2356 when N_Op_Le =>
2357 if Llo > Rhi then
2358 Set_False;
2359 elsif Lhi <= Rlo then
2360 Set_True;
2361 end if;
2362
2363 when N_Op_Lt =>
2364 if Llo >= Rhi then
456cbfa5 2365 Set_False;
b6b5cca8
AC
2366 elsif Lhi < Rlo then
2367 Set_True;
456cbfa5
AC
2368 end if;
2369
2370 when N_Op_Ne =>
2371 if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
456cbfa5 2372 Set_False;
a40ada7e
RD
2373 elsif Llo > Rhi or else Lhi < Rlo then
2374 Set_True;
456cbfa5 2375 end if;
65f7ed64 2376 end case;
456cbfa5 2377
65f7ed64 2378 -- All done if we did the rewrite
456cbfa5 2379
65f7ed64
AC
2380 if Nkind (N) not in N_Op_Compare then
2381 return;
2382 end if;
456cbfa5
AC
2383 end if;
2384
2385 -- Otherwise, time to do the comparison
2386
2387 declare
2388 Ltype : constant Entity_Id := Etype (Left_Opnd (N));
2389 Rtype : constant Entity_Id := Etype (Right_Opnd (N));
2390
2391 begin
2392 -- If the two operands have the same signed integer type we are
2393 -- all set, nothing more to do. This is the case where either
2394 -- both operands were unchanged, or we rewrote both of them to
2395 -- be Long_Long_Integer.
2396
2397 -- Note: Entity for the comparison may be wrong, but it's not worth
2398 -- the effort to change it, since the back end does not use it.
2399
2400 if Is_Signed_Integer_Type (Ltype)
2401 and then Base_Type (Ltype) = Base_Type (Rtype)
2402 then
2403 return;
2404
2405 -- Here if bignums are involved (can only happen in ELIMINATED mode)
2406
2407 elsif Is_RTE (Ltype, RE_Bignum) or else Is_RTE (Rtype, RE_Bignum) then
2408 declare
2409 Left : Node_Id := Left_Opnd (N);
2410 Right : Node_Id := Right_Opnd (N);
2411 -- Bignum references for left and right operands
2412
2413 begin
2414 if not Is_RTE (Ltype, RE_Bignum) then
2415 Left := Convert_To_Bignum (Left);
2416 elsif not Is_RTE (Rtype, RE_Bignum) then
2417 Right := Convert_To_Bignum (Right);
2418 end if;
2419
71fb4dc8 2420 -- We rewrite our node with:
456cbfa5 2421
71fb4dc8
AC
2422 -- do
2423 -- Bnn : Result_Type;
2424 -- declare
2425 -- M : Mark_Id := SS_Mark;
2426 -- begin
2427 -- Bnn := Big_xx (Left, Right); (xx = EQ, NT etc)
2428 -- SS_Release (M);
2429 -- end;
2430 -- in
2431 -- Bnn
2432 -- end
456cbfa5
AC
2433
2434 declare
71fb4dc8 2435 Blk : constant Node_Id := Make_Bignum_Block (Loc);
456cbfa5
AC
2436 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
2437 Ent : RE_Id;
2438
2439 begin
2440 case N_Op_Compare (Nkind (N)) is
2441 when N_Op_Eq => Ent := RE_Big_EQ;
2442 when N_Op_Ge => Ent := RE_Big_GE;
2443 when N_Op_Gt => Ent := RE_Big_GT;
2444 when N_Op_Le => Ent := RE_Big_LE;
2445 when N_Op_Lt => Ent := RE_Big_LT;
2446 when N_Op_Ne => Ent := RE_Big_NE;
2447 end case;
2448
71fb4dc8 2449 -- Insert assignment to Bnn into the bignum block
456cbfa5
AC
2450
2451 Insert_Before
2452 (First (Statements (Handled_Statement_Sequence (Blk))),
2453 Make_Assignment_Statement (Loc,
2454 Name => New_Occurrence_Of (Bnn, Loc),
2455 Expression =>
2456 Make_Function_Call (Loc,
2457 Name =>
2458 New_Occurrence_Of (RTE (Ent), Loc),
2459 Parameter_Associations => New_List (Left, Right))));
2460
71fb4dc8
AC
2461 -- Now do the rewrite with expression actions
2462
2463 Rewrite (N,
2464 Make_Expression_With_Actions (Loc,
2465 Actions => New_List (
2466 Make_Object_Declaration (Loc,
2467 Defining_Identifier => Bnn,
2468 Object_Definition =>
2469 New_Occurrence_Of (Result_Type, Loc)),
2470 Blk),
2471 Expression => New_Occurrence_Of (Bnn, Loc)));
2472 Analyze_And_Resolve (N, Result_Type);
456cbfa5
AC
2473 end;
2474 end;
2475
2476 -- No bignums involved, but types are different, so we must have
2477 -- rewritten one of the operands as a Long_Long_Integer but not
2478 -- the other one.
2479
2480 -- If left operand is Long_Long_Integer, convert right operand
2481 -- and we are done (with a comparison of two Long_Long_Integers).
2482
2483 elsif Ltype = LLIB then
2484 Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
2485 Analyze_And_Resolve (Right_Opnd (N), LLIB, Suppress => All_Checks);
2486 return;
2487
2488 -- If right operand is Long_Long_Integer, convert left operand
2489 -- and we are done (with a comparison of two Long_Long_Integers).
2490
2491 -- This is the only remaining possibility
2492
2493 else pragma Assert (Rtype = LLIB);
2494 Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
2495 Analyze_And_Resolve (Left_Opnd (N), LLIB, Suppress => All_Checks);
2496 return;
2497 end if;
2498 end;
2499 end Expand_Compare_Minimize_Eliminate_Overflow;
2500
70482933
RK
2501 -------------------------------
2502 -- Expand_Composite_Equality --
2503 -------------------------------
2504
2505 -- This function is only called for comparing internal fields of composite
2506 -- types when these fields are themselves composites. This is a special
2507 -- case because it is not possible to respect normal Ada visibility rules.
2508
2509 function Expand_Composite_Equality
2510 (Nod : Node_Id;
2511 Typ : Entity_Id;
2512 Lhs : Node_Id;
2513 Rhs : Node_Id;
2e071734 2514 Bodies : List_Id) return Node_Id
70482933
RK
2515 is
2516 Loc : constant Source_Ptr := Sloc (Nod);
2517 Full_Type : Entity_Id;
2518 Prim : Elmt_Id;
2519 Eq_Op : Entity_Id;
2520
7efc3f2d
AC
2521 function Find_Primitive_Eq return Node_Id;
2522 -- AI05-0123: Locate primitive equality for type if it exists, and
2523 -- build the corresponding call. If operation is abstract, replace
2524 -- call with an explicit raise. Return Empty if there is no primitive.
2525
2526 -----------------------
2527 -- Find_Primitive_Eq --
2528 -----------------------
2529
2530 function Find_Primitive_Eq return Node_Id is
2531 Prim_E : Elmt_Id;
2532 Prim : Node_Id;
2533
2534 begin
2535 Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
2536 while Present (Prim_E) loop
2537 Prim := Node (Prim_E);
2538
2539 -- Locate primitive equality with the right signature
2540
2541 if Chars (Prim) = Name_Op_Eq
2542 and then Etype (First_Formal (Prim)) =
39ade2f9 2543 Etype (Next_Formal (First_Formal (Prim)))
7efc3f2d
AC
2544 and then Etype (Prim) = Standard_Boolean
2545 then
2546 if Is_Abstract_Subprogram (Prim) then
2547 return
2548 Make_Raise_Program_Error (Loc,
2549 Reason => PE_Explicit_Raise);
2550
2551 else
2552 return
2553 Make_Function_Call (Loc,
e4494292 2554 Name => New_Occurrence_Of (Prim, Loc),
7efc3f2d
AC
2555 Parameter_Associations => New_List (Lhs, Rhs));
2556 end if;
2557 end if;
2558
2559 Next_Elmt (Prim_E);
2560 end loop;
2561
2562 -- If not found, predefined operation will be used
2563
2564 return Empty;
2565 end Find_Primitive_Eq;
2566
2567 -- Start of processing for Expand_Composite_Equality
2568
70482933
RK
2569 begin
2570 if Is_Private_Type (Typ) then
2571 Full_Type := Underlying_Type (Typ);
2572 else
2573 Full_Type := Typ;
2574 end if;
2575
ced8450b
ES
2576 -- If the private type has no completion the context may be the
2577 -- expansion of a composite equality for a composite type with some
2578 -- still incomplete components. The expression will not be analyzed
2579 -- until the enclosing type is completed, at which point this will be
2580 -- properly expanded, unless there is a bona fide completion error.
70482933
RK
2581
2582 if No (Full_Type) then
ced8450b 2583 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
70482933
RK
2584 end if;
2585
2586 Full_Type := Base_Type (Full_Type);
2587
da1b76c1
HK
2588 -- When the base type itself is private, use the full view to expand
2589 -- the composite equality.
2590
2591 if Is_Private_Type (Full_Type) then
2592 Full_Type := Underlying_Type (Full_Type);
2593 end if;
2594
16788d44
RD
2595 -- Case of array types
2596
70482933
RK
2597 if Is_Array_Type (Full_Type) then
2598
2599 -- If the operand is an elementary type other than a floating-point
2600 -- type, then we can simply use the built-in block bitwise equality,
2601 -- since the predefined equality operators always apply and bitwise
2602 -- equality is fine for all these cases.
2603
2604 if Is_Elementary_Type (Component_Type (Full_Type))
2605 and then not Is_Floating_Point_Type (Component_Type (Full_Type))
2606 then
39ade2f9 2607 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
70482933 2608
685094bf
RD
2609 -- For composite component types, and floating-point types, use the
2610 -- expansion. This deals with tagged component types (where we use
2611 -- the applicable equality routine) and floating-point, (where we
2612 -- need to worry about negative zeroes), and also the case of any
2613 -- composite type recursively containing such fields.
70482933
RK
2614
2615 else
0da2c8ac 2616 return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Full_Type);
70482933
RK
2617 end if;
2618
16788d44
RD
2619 -- Case of tagged record types
2620
70482933
RK
2621 elsif Is_Tagged_Type (Full_Type) then
2622
2623 -- Call the primitive operation "=" of this type
2624
2625 if Is_Class_Wide_Type (Full_Type) then
2626 Full_Type := Root_Type (Full_Type);
2627 end if;
2628
685094bf
RD
2629 -- If this is derived from an untagged private type completed with a
2630 -- tagged type, it does not have a full view, so we use the primitive
2631 -- operations of the private type. This check should no longer be
2632 -- necessary when these types receive their full views ???
70482933
RK
2633
2634 if Is_Private_Type (Typ)
2635 and then not Is_Tagged_Type (Typ)
2636 and then not Is_Controlled (Typ)
2637 and then Is_Derived_Type (Typ)
2638 and then No (Full_View (Typ))
2639 then
2640 Prim := First_Elmt (Collect_Primitive_Operations (Typ));
2641 else
2642 Prim := First_Elmt (Primitive_Operations (Full_Type));
2643 end if;
2644
2645 loop
2646 Eq_Op := Node (Prim);
2647 exit when Chars (Eq_Op) = Name_Op_Eq
2648 and then Etype (First_Formal (Eq_Op)) =
e6f69614
AC
2649 Etype (Next_Formal (First_Formal (Eq_Op)))
2650 and then Base_Type (Etype (Eq_Op)) = Standard_Boolean;
70482933
RK
2651 Next_Elmt (Prim);
2652 pragma Assert (Present (Prim));
2653 end loop;
2654
2655 Eq_Op := Node (Prim);
2656
2657 return
2658 Make_Function_Call (Loc,
e4494292 2659 Name => New_Occurrence_Of (Eq_Op, Loc),
70482933
RK
2660 Parameter_Associations =>
2661 New_List
2662 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
2663 Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
2664
16788d44
RD
2665 -- Case of untagged record types
2666
70482933 2667 elsif Is_Record_Type (Full_Type) then
fbf5a39b 2668 Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
70482933
RK
2669
2670 if Present (Eq_Op) then
2671 if Etype (First_Formal (Eq_Op)) /= Full_Type then
2672
685094bf
RD
2673 -- Inherited equality from parent type. Convert the actuals to
2674 -- match signature of operation.
70482933
RK
2675
2676 declare
fbf5a39b 2677 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
70482933
RK
2678
2679 begin
2680 return
2681 Make_Function_Call (Loc,
e4494292 2682 Name => New_Occurrence_Of (Eq_Op, Loc),
39ade2f9
AC
2683 Parameter_Associations => New_List (
2684 OK_Convert_To (T, Lhs),
2685 OK_Convert_To (T, Rhs)));
70482933
RK
2686 end;
2687
2688 else
5d09245e
AC
2689 -- Comparison between Unchecked_Union components
2690
2691 if Is_Unchecked_Union (Full_Type) then
2692 declare
2693 Lhs_Type : Node_Id := Full_Type;
2694 Rhs_Type : Node_Id := Full_Type;
2695 Lhs_Discr_Val : Node_Id;
2696 Rhs_Discr_Val : Node_Id;
2697
2698 begin
2699 -- Lhs subtype
2700
2701 if Nkind (Lhs) = N_Selected_Component then
2702 Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
2703 end if;
2704
2705 -- Rhs subtype
2706
2707 if Nkind (Rhs) = N_Selected_Component then
2708 Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
2709 end if;
2710
2711 -- Lhs of the composite equality
2712
2713 if Is_Constrained (Lhs_Type) then
2714
685094bf 2715 -- Since the enclosing record type can never be an
5d09245e
AC
2716 -- Unchecked_Union (this code is executed for records
2717 -- that do not have variants), we may reference its
2718 -- discriminant(s).
2719
2720 if Nkind (Lhs) = N_Selected_Component
533369aa
AC
2721 and then Has_Per_Object_Constraint
2722 (Entity (Selector_Name (Lhs)))
5d09245e
AC
2723 then
2724 Lhs_Discr_Val :=
2725 Make_Selected_Component (Loc,
39ade2f9 2726 Prefix => Prefix (Lhs),
5d09245e 2727 Selector_Name =>
39ade2f9
AC
2728 New_Copy
2729 (Get_Discriminant_Value
2730 (First_Discriminant (Lhs_Type),
2731 Lhs_Type,
2732 Stored_Constraint (Lhs_Type))));
5d09245e
AC
2733
2734 else
39ade2f9
AC
2735 Lhs_Discr_Val :=
2736 New_Copy
2737 (Get_Discriminant_Value
2738 (First_Discriminant (Lhs_Type),
2739 Lhs_Type,
2740 Stored_Constraint (Lhs_Type)));
5d09245e
AC
2741
2742 end if;
2743 else
2744 -- It is not possible to infer the discriminant since
2745 -- the subtype is not constrained.
2746
8aceda64 2747 return
5d09245e 2748 Make_Raise_Program_Error (Loc,
8aceda64 2749 Reason => PE_Unchecked_Union_Restriction);
5d09245e
AC
2750 end if;
2751
2752 -- Rhs of the composite equality
2753
2754 if Is_Constrained (Rhs_Type) then
2755 if Nkind (Rhs) = N_Selected_Component
39ade2f9
AC
2756 and then Has_Per_Object_Constraint
2757 (Entity (Selector_Name (Rhs)))
5d09245e
AC
2758 then
2759 Rhs_Discr_Val :=
2760 Make_Selected_Component (Loc,
39ade2f9 2761 Prefix => Prefix (Rhs),
5d09245e 2762 Selector_Name =>
39ade2f9
AC
2763 New_Copy
2764 (Get_Discriminant_Value
2765 (First_Discriminant (Rhs_Type),
2766 Rhs_Type,
2767 Stored_Constraint (Rhs_Type))));
5d09245e
AC
2768
2769 else
39ade2f9
AC
2770 Rhs_Discr_Val :=
2771 New_Copy
2772 (Get_Discriminant_Value
2773 (First_Discriminant (Rhs_Type),
2774 Rhs_Type,
2775 Stored_Constraint (Rhs_Type)));
5d09245e
AC
2776
2777 end if;
2778 else
8aceda64 2779 return
5d09245e 2780 Make_Raise_Program_Error (Loc,
8aceda64 2781 Reason => PE_Unchecked_Union_Restriction);
5d09245e
AC
2782 end if;
2783
2784 -- Call the TSS equality function with the inferred
2785 -- discriminant values.
2786
2787 return
2788 Make_Function_Call (Loc,
e4494292 2789 Name => New_Occurrence_Of (Eq_Op, Loc),
5d09245e
AC
2790 Parameter_Associations => New_List (
2791 Lhs,
2792 Rhs,
2793 Lhs_Discr_Val,
2794 Rhs_Discr_Val));
2795 end;
d151d6a3 2796
316e3a13
RD
2797 -- All cases other than comparing Unchecked_Union types
2798
d151d6a3 2799 else
7f1a5156
EB
2800 declare
2801 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
7f1a5156
EB
2802 begin
2803 return
2804 Make_Function_Call (Loc,
316e3a13
RD
2805 Name =>
2806 New_Occurrence_Of (Eq_Op, Loc),
7f1a5156
EB
2807 Parameter_Associations => New_List (
2808 OK_Convert_To (T, Lhs),
2809 OK_Convert_To (T, Rhs)));
2810 end;
5d09245e 2811 end if;
d151d6a3 2812 end if;
5d09245e 2813
3058f181
BD
2814 -- Equality composes in Ada 2012 for untagged record types. It also
2815 -- composes for bounded strings, because they are part of the
2816 -- predefined environment. We could make it compose for bounded
2817 -- strings by making them tagged, or by making sure all subcomponents
2818 -- are set to the same value, even when not used. Instead, we have
2819 -- this special case in the compiler, because it's more efficient.
2820
2821 elsif Ada_Version >= Ada_2012 or else Is_Bounded_String (Typ) then
5d09245e 2822
08daa782 2823 -- If no TSS has been created for the type, check whether there is
7efc3f2d 2824 -- a primitive equality declared for it.
d151d6a3
AC
2825
2826 declare
3058f181 2827 Op : constant Node_Id := Find_Primitive_Eq;
d151d6a3
AC
2828
2829 begin
a1fc903a
AC
2830 -- Use user-defined primitive if it exists, otherwise use
2831 -- predefined equality.
2832
3058f181
BD
2833 if Present (Op) then
2834 return Op;
7efc3f2d 2835 else
7efc3f2d
AC
2836 return Make_Op_Eq (Loc, Lhs, Rhs);
2837 end if;
d151d6a3
AC
2838 end;
2839
70482933
RK
2840 else
2841 return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
2842 end if;
2843
16788d44 2844 -- Non-composite types (always use predefined equality)
70482933 2845
16788d44 2846 else
70482933
RK
2847 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2848 end if;
2849 end Expand_Composite_Equality;
2850
fdac1f80
AC
2851 ------------------------
2852 -- Expand_Concatenate --
2853 ------------------------
70482933 2854
fdac1f80
AC
2855 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id) is
2856 Loc : constant Source_Ptr := Sloc (Cnode);
70482933 2857
fdac1f80
AC
2858 Atyp : constant Entity_Id := Base_Type (Etype (Cnode));
2859 -- Result type of concatenation
70482933 2860
fdac1f80
AC
2861 Ctyp : constant Entity_Id := Base_Type (Component_Type (Etype (Cnode)));
2862 -- Component type. Elements of this component type can appear as one
2863 -- of the operands of concatenation as well as arrays.
70482933 2864
ecc4ddde
AC
2865 Istyp : constant Entity_Id := Etype (First_Index (Atyp));
2866 -- Index subtype
2867
2868 Ityp : constant Entity_Id := Base_Type (Istyp);
2869 -- Index type. This is the base type of the index subtype, and is used
2870 -- for all computed bounds (which may be out of range of Istyp in the
2871 -- case of null ranges).
70482933 2872
46ff89f3 2873 Artyp : Entity_Id;
fdac1f80
AC
2874 -- This is the type we use to do arithmetic to compute the bounds and
2875 -- lengths of operands. The choice of this type is a little subtle and
2876 -- is discussed in a separate section at the start of the body code.
70482933 2877
fdac1f80
AC
2878 Concatenation_Error : exception;
2879 -- Raised if concatenation is sure to raise a CE
70482933 2880
0ac73189
AC
2881 Result_May_Be_Null : Boolean := True;
2882 -- Reset to False if at least one operand is encountered which is known
2883 -- at compile time to be non-null. Used for handling the special case
2884 -- of setting the high bound to the last operand high bound for a null
2885 -- result, thus ensuring a proper high bound in the super-flat case.
2886
df46b832 2887 N : constant Nat := List_Length (Opnds);
fdac1f80 2888 -- Number of concatenation operands including possibly null operands
df46b832
AC
2889
2890 NN : Nat := 0;
a29262fd
AC
2891 -- Number of operands excluding any known to be null, except that the
2892 -- last operand is always retained, in case it provides the bounds for
2893 -- a null result.
2894
2895 Opnd : Node_Id;
2896 -- Current operand being processed in the loop through operands. After
2897 -- this loop is complete, always contains the last operand (which is not
2898 -- the same as Operands (NN), since null operands are skipped).
df46b832
AC
2899
2900 -- Arrays describing the operands, only the first NN entries of each
2901 -- array are set (NN < N when we exclude known null operands).
2902
2903 Is_Fixed_Length : array (1 .. N) of Boolean;
2904 -- True if length of corresponding operand known at compile time
2905
2906 Operands : array (1 .. N) of Node_Id;
a29262fd
AC
2907 -- Set to the corresponding entry in the Opnds list (but note that null
2908 -- operands are excluded, so not all entries in the list are stored).
df46b832
AC
2909
2910 Fixed_Length : array (1 .. N) of Uint;
fdac1f80
AC
2911 -- Set to length of operand. Entries in this array are set only if the
2912 -- corresponding entry in Is_Fixed_Length is True.
df46b832 2913
0ac73189
AC
2914 Opnd_Low_Bound : array (1 .. N) of Node_Id;
2915 -- Set to lower bound of operand. Either an integer literal in the case
2916 -- where the bound is known at compile time, else actual lower bound.
2917 -- The operand low bound is of type Ityp.
2918
df46b832
AC
2919 Var_Length : array (1 .. N) of Entity_Id;
2920 -- Set to an entity of type Natural that contains the length of an
2921 -- operand whose length is not known at compile time. Entries in this
2922 -- array are set only if the corresponding entry in Is_Fixed_Length
46ff89f3 2923 -- is False. The entity is of type Artyp.
df46b832
AC
2924
2925 Aggr_Length : array (0 .. N) of Node_Id;
fdac1f80
AC
2926 -- The J'th entry in an expression node that represents the total length
2927 -- of operands 1 through J. It is either an integer literal node, or a
2928 -- reference to a constant entity with the right value, so it is fine
2929 -- to just do a Copy_Node to get an appropriate copy. The extra zero'th
46ff89f3 2930 -- entry always is set to zero. The length is of type Artyp.
df46b832
AC
2931
2932 Low_Bound : Node_Id;
0ac73189
AC
2933 -- A tree node representing the low bound of the result (of type Ityp).
2934 -- This is either an integer literal node, or an identifier reference to
2935 -- a constant entity initialized to the appropriate value.
2936
88a27b18
AC
2937 Last_Opnd_Low_Bound : Node_Id;
2938 -- A tree node representing the low bound of the last operand. This
2939 -- need only be set if the result could be null. It is used for the
2940 -- special case of setting the right low bound for a null result.
2941 -- This is of type Ityp.
2942
a29262fd
AC
2943 Last_Opnd_High_Bound : Node_Id;
2944 -- A tree node representing the high bound of the last operand. This
2945 -- need only be set if the result could be null. It is used for the
2946 -- special case of setting the right high bound for a null result.
2947 -- This is of type Ityp.
2948
0ac73189
AC
2949 High_Bound : Node_Id;
2950 -- A tree node representing the high bound of the result (of type Ityp)
df46b832
AC
2951
2952 Result : Node_Id;
0ac73189 2953 -- Result of the concatenation (of type Ityp)
df46b832 2954
d0f8d157 2955 Actions : constant List_Id := New_List;
4c9fe6c7 2956 -- Collect actions to be inserted
d0f8d157 2957
fa969310 2958 Known_Non_Null_Operand_Seen : Boolean;
308e6f3a 2959 -- Set True during generation of the assignments of operands into
fa969310
AC
2960 -- result once an operand known to be non-null has been seen.
2961
2962 function Make_Artyp_Literal (Val : Nat) return Node_Id;
2963 -- This function makes an N_Integer_Literal node that is returned in
2964 -- analyzed form with the type set to Artyp. Importantly this literal
2965 -- is not flagged as static, so that if we do computations with it that
2966 -- result in statically detected out of range conditions, we will not
2967 -- generate error messages but instead warning messages.
2968
46ff89f3 2969 function To_Artyp (X : Node_Id) return Node_Id;
fdac1f80 2970 -- Given a node of type Ityp, returns the corresponding value of type
76c597a1
AC
2971 -- Artyp. For non-enumeration types, this is a plain integer conversion.
2972 -- For enum types, the Pos of the value is returned.
fdac1f80
AC
2973
2974 function To_Ityp (X : Node_Id) return Node_Id;
0ac73189 2975 -- The inverse function (uses Val in the case of enumeration types)
fdac1f80 2976
fa969310
AC
2977 ------------------------
2978 -- Make_Artyp_Literal --
2979 ------------------------
2980
2981 function Make_Artyp_Literal (Val : Nat) return Node_Id is
2982 Result : constant Node_Id := Make_Integer_Literal (Loc, Val);
2983 begin
2984 Set_Etype (Result, Artyp);
2985 Set_Analyzed (Result, True);
2986 Set_Is_Static_Expression (Result, False);
2987 return Result;
2988 end Make_Artyp_Literal;
76c597a1 2989
fdac1f80 2990 --------------
46ff89f3 2991 -- To_Artyp --
fdac1f80
AC
2992 --------------
2993
46ff89f3 2994 function To_Artyp (X : Node_Id) return Node_Id is
fdac1f80 2995 begin
46ff89f3 2996 if Ityp = Base_Type (Artyp) then
fdac1f80
AC
2997 return X;
2998
2999 elsif Is_Enumeration_Type (Ityp) then
3000 return
3001 Make_Attribute_Reference (Loc,
3002 Prefix => New_Occurrence_Of (Ityp, Loc),
3003 Attribute_Name => Name_Pos,
3004 Expressions => New_List (X));
3005
3006 else
46ff89f3 3007 return Convert_To (Artyp, X);
fdac1f80 3008 end if;
46ff89f3 3009 end To_Artyp;
fdac1f80
AC
3010
3011 -------------
3012 -- To_Ityp --
3013 -------------
3014
3015 function To_Ityp (X : Node_Id) return Node_Id is
3016 begin
2fc05e3d 3017 if Is_Enumeration_Type (Ityp) then
fdac1f80
AC
3018 return
3019 Make_Attribute_Reference (Loc,
3020 Prefix => New_Occurrence_Of (Ityp, Loc),
3021 Attribute_Name => Name_Val,
3022 Expressions => New_List (X));
3023
3024 -- Case where we will do a type conversion
3025
3026 else
76c597a1
AC
3027 if Ityp = Base_Type (Artyp) then
3028 return X;
fdac1f80 3029 else
76c597a1 3030 return Convert_To (Ityp, X);
fdac1f80
AC
3031 end if;
3032 end if;
3033 end To_Ityp;
3034
3035 -- Local Declarations
3036
00ba7be8
AC
3037 Lib_Level_Target : constant Boolean :=
3038 Nkind (Parent (Cnode)) = N_Object_Declaration
3039 and then
3040 Is_Library_Level_Entity (Defining_Identifier (Parent (Cnode)));
3041
3042 -- If the concatenation declares a library level entity, we call the
3043 -- built-in concatenation routines to prevent code bloat, regardless
3044 -- of optimization level. This is space-efficient, and prevent linking
3045 -- problems when units are compiled with different optimizations.
3046
0ac73189
AC
3047 Opnd_Typ : Entity_Id;
3048 Ent : Entity_Id;
3049 Len : Uint;
3050 J : Nat;
3051 Clen : Node_Id;
3052 Set : Boolean;
70482933 3053
f46faa08
AC
3054 -- Start of processing for Expand_Concatenate
3055
70482933 3056 begin
fdac1f80
AC
3057 -- Choose an appropriate computational type
3058
3059 -- We will be doing calculations of lengths and bounds in this routine
3060 -- and computing one from the other in some cases, e.g. getting the high
3061 -- bound by adding the length-1 to the low bound.
3062
3063 -- We can't just use the index type, or even its base type for this
3064 -- purpose for two reasons. First it might be an enumeration type which
308e6f3a
RW
3065 -- is not suitable for computations of any kind, and second it may
3066 -- simply not have enough range. For example if the index type is
3067 -- -128..+127 then lengths can be up to 256, which is out of range of
3068 -- the type.
fdac1f80
AC
3069
3070 -- For enumeration types, we can simply use Standard_Integer, this is
3071 -- sufficient since the actual number of enumeration literals cannot
3072 -- possibly exceed the range of integer (remember we will be doing the
0ac73189 3073 -- arithmetic with POS values, not representation values).
fdac1f80
AC
3074
3075 if Is_Enumeration_Type (Ityp) then
46ff89f3 3076 Artyp := Standard_Integer;
fdac1f80 3077
59262ebb
AC
3078 -- If index type is Positive, we use the standard unsigned type, to give
3079 -- more room on the top of the range, obviating the need for an overflow
3080 -- check when creating the upper bound. This is needed to avoid junk
3081 -- overflow checks in the common case of String types.
3082
3083 -- ??? Disabled for now
3084
3085 -- elsif Istyp = Standard_Positive then
3086 -- Artyp := Standard_Unsigned;
3087
2fc05e3d
AC
3088 -- For modular types, we use a 32-bit modular type for types whose size
3089 -- is in the range 1-31 bits. For 32-bit unsigned types, we use the
3090 -- identity type, and for larger unsigned types we use 64-bits.
fdac1f80 3091
2fc05e3d 3092 elsif Is_Modular_Integer_Type (Ityp) then
ecc4ddde 3093 if RM_Size (Ityp) < RM_Size (Standard_Unsigned) then
46ff89f3 3094 Artyp := Standard_Unsigned;
ecc4ddde 3095 elsif RM_Size (Ityp) = RM_Size (Standard_Unsigned) then
46ff89f3 3096 Artyp := Ityp;
fdac1f80 3097 else
46ff89f3 3098 Artyp := RTE (RE_Long_Long_Unsigned);
fdac1f80
AC
3099 end if;
3100
2fc05e3d 3101 -- Similar treatment for signed types
fdac1f80
AC
3102
3103 else
ecc4ddde 3104 if RM_Size (Ityp) < RM_Size (Standard_Integer) then
46ff89f3 3105 Artyp := Standard_Integer;
ecc4ddde 3106 elsif RM_Size (Ityp) = RM_Size (Standard_Integer) then
46ff89f3 3107 Artyp := Ityp;
fdac1f80 3108 else
46ff89f3 3109 Artyp := Standard_Long_Long_Integer;
fdac1f80
AC
3110 end if;
3111 end if;
3112
fa969310
AC
3113 -- Supply dummy entry at start of length array
3114
3115 Aggr_Length (0) := Make_Artyp_Literal (0);
3116
fdac1f80 3117 -- Go through operands setting up the above arrays
70482933 3118
df46b832
AC
3119 J := 1;
3120 while J <= N loop
3121 Opnd := Remove_Head (Opnds);
0ac73189 3122 Opnd_Typ := Etype (Opnd);
fdac1f80
AC
3123
3124 -- The parent got messed up when we put the operands in a list,
d347f572
AC
3125 -- so now put back the proper parent for the saved operand, that
3126 -- is to say the concatenation node, to make sure that each operand
3127 -- is seen as a subexpression, e.g. if actions must be inserted.
fdac1f80 3128
d347f572 3129 Set_Parent (Opnd, Cnode);
fdac1f80
AC
3130
3131 -- Set will be True when we have setup one entry in the array
3132
df46b832
AC
3133 Set := False;
3134
fdac1f80 3135 -- Singleton element (or character literal) case
df46b832 3136
0ac73189 3137 if Base_Type (Opnd_Typ) = Ctyp then
df46b832
AC
3138 NN := NN + 1;
3139 Operands (NN) := Opnd;
3140 Is_Fixed_Length (NN) := True;
3141 Fixed_Length (NN) := Uint_1;
0ac73189 3142 Result_May_Be_Null := False;
fdac1f80 3143
a29262fd
AC
3144 -- Set low bound of operand (no need to set Last_Opnd_High_Bound
3145 -- since we know that the result cannot be null).
fdac1f80 3146
0ac73189
AC
3147 Opnd_Low_Bound (NN) :=
3148 Make_Attribute_Reference (Loc,
e4494292 3149 Prefix => New_Occurrence_Of (Istyp, Loc),
0ac73189
AC
3150 Attribute_Name => Name_First);
3151
df46b832
AC
3152 Set := True;
3153
fdac1f80 3154 -- String literal case (can only occur for strings of course)
df46b832
AC
3155
3156 elsif Nkind (Opnd) = N_String_Literal then
0ac73189 3157 Len := String_Literal_Length (Opnd_Typ);
df46b832 3158
a29262fd
AC
3159 if Len /= 0 then
3160 Result_May_Be_Null := False;
3161 end if;
3162
88a27b18 3163 -- Capture last operand low and high bound if result could be null
a29262fd
AC
3164
3165 if J = N and then Result_May_Be_Null then
88a27b18
AC
3166 Last_Opnd_Low_Bound :=
3167 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
3168
a29262fd 3169 Last_Opnd_High_Bound :=
88a27b18 3170 Make_Op_Subtract (Loc,
a29262fd
AC
3171 Left_Opnd =>
3172 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
59262ebb 3173 Right_Opnd => Make_Integer_Literal (Loc, 1));
a29262fd
AC
3174 end if;
3175
3176 -- Skip null string literal
fdac1f80 3177
0ac73189 3178 if J < N and then Len = 0 then
df46b832
AC
3179 goto Continue;
3180 end if;
3181
3182 NN := NN + 1;
3183 Operands (NN) := Opnd;
3184 Is_Fixed_Length (NN) := True;
0ac73189
AC
3185
3186 -- Set length and bounds
3187
df46b832 3188 Fixed_Length (NN) := Len;
0ac73189
AC
3189
3190 Opnd_Low_Bound (NN) :=
3191 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
3192
df46b832
AC
3193 Set := True;
3194
3195 -- All other cases
3196
3197 else
3198 -- Check constrained case with known bounds
3199
0ac73189 3200 if Is_Constrained (Opnd_Typ) then
df46b832 3201 declare
df46b832
AC
3202 Index : constant Node_Id := First_Index (Opnd_Typ);
3203 Indx_Typ : constant Entity_Id := Etype (Index);
3204 Lo : constant Node_Id := Type_Low_Bound (Indx_Typ);
3205 Hi : constant Node_Id := Type_High_Bound (Indx_Typ);
3206
3207 begin
fdac1f80
AC
3208 -- Fixed length constrained array type with known at compile
3209 -- time bounds is last case of fixed length operand.
df46b832
AC
3210
3211 if Compile_Time_Known_Value (Lo)
3212 and then
3213 Compile_Time_Known_Value (Hi)
3214 then
3215 declare
3216 Loval : constant Uint := Expr_Value (Lo);
3217 Hival : constant Uint := Expr_Value (Hi);
3218 Len : constant Uint :=
3219 UI_Max (Hival - Loval + 1, Uint_0);
3220
3221 begin
0ac73189
AC
3222 if Len > 0 then
3223 Result_May_Be_Null := False;
df46b832 3224 end if;
0ac73189 3225
88a27b18 3226 -- Capture last operand bounds if result could be null
a29262fd
AC
3227
3228 if J = N and then Result_May_Be_Null then
88a27b18
AC
3229 Last_Opnd_Low_Bound :=
3230 Convert_To (Ityp,
3231 Make_Integer_Literal (Loc, Expr_Value (Lo)));
3232
a29262fd
AC
3233 Last_Opnd_High_Bound :=
3234 Convert_To (Ityp,
39ade2f9 3235 Make_Integer_Literal (Loc, Expr_Value (Hi)));
a29262fd
AC
3236 end if;
3237
3238 -- Exclude null length case unless last operand
0ac73189 3239
a29262fd 3240 if J < N and then Len = 0 then
0ac73189
AC
3241 goto Continue;
3242 end if;
3243
3244 NN := NN + 1;
3245 Operands (NN) := Opnd;
3246 Is_Fixed_Length (NN) := True;
3247 Fixed_Length (NN) := Len;
3248
39ade2f9
AC
3249 Opnd_Low_Bound (NN) :=
3250 To_Ityp
3251 (Make_Integer_Literal (Loc, Expr_Value (Lo)));
0ac73189 3252 Set := True;
df46b832
AC
3253 end;
3254 end if;
3255 end;
3256 end if;
3257
0ac73189
AC
3258 -- All cases where the length is not known at compile time, or the
3259 -- special case of an operand which is known to be null but has a
3260 -- lower bound other than 1 or is other than a string type.
df46b832
AC
3261
3262 if not Set then
3263 NN := NN + 1;
0ac73189
AC
3264
3265 -- Capture operand bounds
3266
3267 Opnd_Low_Bound (NN) :=
3268 Make_Attribute_Reference (Loc,
3269 Prefix =>
3270 Duplicate_Subexpr (Opnd, Name_Req => True),
3271 Attribute_Name => Name_First);
3272
88a27b18
AC
3273 -- Capture last operand bounds if result could be null
3274
a29262fd 3275 if J = N and Result_May_Be_Null then
88a27b18
AC
3276 Last_Opnd_Low_Bound :=
3277 Convert_To (Ityp,
3278 Make_Attribute_Reference (Loc,
3279 Prefix =>
3280 Duplicate_Subexpr (Opnd, Name_Req => True),
3281 Attribute_Name => Name_First));
3282
a29262fd
AC
3283 Last_Opnd_High_Bound :=
3284 Convert_To (Ityp,
3285 Make_Attribute_Reference (Loc,
3286 Prefix =>
3287 Duplicate_Subexpr (Opnd, Name_Req => True),
3288 Attribute_Name => Name_Last));
3289 end if;
0ac73189
AC
3290
3291 -- Capture length of operand in entity
3292
df46b832
AC
3293 Operands (NN) := Opnd;
3294 Is_Fixed_Length (NN) := False;
3295
191fcb3a 3296 Var_Length (NN) := Make_Temporary (Loc, 'L');
df46b832 3297
d0f8d157 3298 Append_To (Actions,
df46b832
AC
3299 Make_Object_Declaration (Loc,
3300 Defining_Identifier => Var_Length (NN),
3301 Constant_Present => True,
39ade2f9 3302 Object_Definition => New_Occurrence_Of (Artyp, Loc),
df46b832
AC
3303 Expression =>
3304 Make_Attribute_Reference (Loc,
3305 Prefix =>
3306 Duplicate_Subexpr (Opnd, Name_Req => True),
d0f8d157 3307 Attribute_Name => Name_Length)));
df46b832
AC
3308 end if;
3309 end if;
3310
3311 -- Set next entry in aggregate length array
3312
3313 -- For first entry, make either integer literal for fixed length
0ac73189 3314 -- or a reference to the saved length for variable length.
df46b832
AC
3315
3316 if NN = 1 then
3317 if Is_Fixed_Length (1) then
39ade2f9 3318 Aggr_Length (1) := Make_Integer_Literal (Loc, Fixed_Length (1));
df46b832 3319 else
e4494292 3320 Aggr_Length (1) := New_Occurrence_Of (Var_Length (1), Loc);
df46b832
AC
3321 end if;
3322
3323 -- If entry is fixed length and only fixed lengths so far, make
3324 -- appropriate new integer literal adding new length.
3325
3326 elsif Is_Fixed_Length (NN)
3327 and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
3328 then
3329 Aggr_Length (NN) :=
3330 Make_Integer_Literal (Loc,
3331 Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));
3332
d0f8d157
AC
3333 -- All other cases, construct an addition node for the length and
3334 -- create an entity initialized to this length.
df46b832
AC
3335
3336 else
191fcb3a 3337 Ent := Make_Temporary (Loc, 'L');
df46b832
AC
3338
3339 if Is_Fixed_Length (NN) then
3340 Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
3341 else
e4494292 3342 Clen := New_Occurrence_Of (Var_Length (NN), Loc);
df46b832
AC
3343 end if;
3344
d0f8d157 3345 Append_To (Actions,
df46b832
AC
3346 Make_Object_Declaration (Loc,
3347 Defining_Identifier => Ent,
3348 Constant_Present => True,
39ade2f9 3349 Object_Definition => New_Occurrence_Of (Artyp, Loc),
df46b832
AC
3350 Expression =>
3351 Make_Op_Add (Loc,
3352 Left_Opnd => New_Copy (Aggr_Length (NN - 1)),
d0f8d157 3353 Right_Opnd => Clen)));
df46b832 3354
76c597a1 3355 Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
df46b832
AC
3356 end if;
3357
3358 <<Continue>>
3359 J := J + 1;
3360 end loop;
3361
a29262fd 3362 -- If we have only skipped null operands, return the last operand
df46b832
AC
3363
3364 if NN = 0 then
a29262fd 3365 Result := Opnd;
df46b832
AC
3366 goto Done;
3367 end if;
3368
3369 -- If we have only one non-null operand, return it and we are done.
3370 -- There is one case in which this cannot be done, and that is when
fdac1f80
AC
3371 -- the sole operand is of the element type, in which case it must be
3372 -- converted to an array, and the easiest way of doing that is to go
df46b832
AC
3373 -- through the normal general circuit.
3374
533369aa 3375 if NN = 1 and then Base_Type (Etype (Operands (1))) /= Ctyp then
df46b832
AC
3376 Result := Operands (1);
3377 goto Done;
3378 end if;
3379
3380 -- Cases where we have a real concatenation
3381
fdac1f80
AC
3382 -- Next step is to find the low bound for the result array that we
3383 -- will allocate. The rules for this are in (RM 4.5.6(5-7)).
3384
3385 -- If the ultimate ancestor of the index subtype is a constrained array
3386 -- definition, then the lower bound is that of the index subtype as
3387 -- specified by (RM 4.5.3(6)).
3388
3389 -- The right test here is to go to the root type, and then the ultimate
3390 -- ancestor is the first subtype of this root type.
3391
3392 if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
0ac73189 3393 Low_Bound :=
fdac1f80
AC
3394 Make_Attribute_Reference (Loc,
3395 Prefix =>
3396 New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
0ac73189 3397 Attribute_Name => Name_First);
df46b832
AC
3398
3399 -- If the first operand in the list has known length we know that
3400 -- the lower bound of the result is the lower bound of this operand.
3401
fdac1f80 3402 elsif Is_Fixed_Length (1) then
0ac73189 3403 Low_Bound := Opnd_Low_Bound (1);
df46b832
AC
3404
3405 -- OK, we don't know the lower bound, we have to build a horrible
9b16cb57 3406 -- if expression node of the form
df46b832
AC
3407
3408 -- if Cond1'Length /= 0 then
0ac73189 3409 -- Opnd1 low bound
df46b832
AC
3410 -- else
3411 -- if Opnd2'Length /= 0 then
0ac73189 3412 -- Opnd2 low bound
df46b832
AC
3413 -- else
3414 -- ...
3415
3416 -- The nesting ends either when we hit an operand whose length is known
3417 -- at compile time, or on reaching the last operand, whose low bound we
3418 -- take unconditionally whether or not it is null. It's easiest to do
3419 -- this with a recursive procedure:
3420
3421 else
3422 declare
3423 function Get_Known_Bound (J : Nat) return Node_Id;
3424 -- Returns the lower bound determined by operands J .. NN
3425
3426 ---------------------
3427 -- Get_Known_Bound --
3428 ---------------------
3429
3430 function Get_Known_Bound (J : Nat) return Node_Id is
df46b832 3431 begin
0ac73189
AC
3432 if Is_Fixed_Length (J) or else J = NN then
3433 return New_Copy (Opnd_Low_Bound (J));
70482933
RK
3434
3435 else
df46b832 3436 return
9b16cb57 3437 Make_If_Expression (Loc,
df46b832
AC
3438 Expressions => New_List (
3439
3440 Make_Op_Ne (Loc,
e4494292
RD
3441 Left_Opnd =>
3442 New_Occurrence_Of (Var_Length (J), Loc),
3443 Right_Opnd =>
3444 Make_Integer_Literal (Loc, 0)),
df46b832 3445
0ac73189 3446 New_Copy (Opnd_Low_Bound (J)),
df46b832 3447 Get_Known_Bound (J + 1)));
70482933 3448 end if;
df46b832 3449 end Get_Known_Bound;
70482933 3450
df46b832 3451 begin
191fcb3a 3452 Ent := Make_Temporary (Loc, 'L');
df46b832 3453
d0f8d157 3454 Append_To (Actions,
df46b832
AC
3455 Make_Object_Declaration (Loc,
3456 Defining_Identifier => Ent,
3457 Constant_Present => True,
0ac73189 3458 Object_Definition => New_Occurrence_Of (Ityp, Loc),
d0f8d157 3459 Expression => Get_Known_Bound (1)));
df46b832 3460
e4494292 3461 Low_Bound := New_Occurrence_Of (Ent, Loc);
df46b832
AC
3462 end;
3463 end if;
70482933 3464
76c597a1
AC
3465 -- Now we can safely compute the upper bound, normally
3466 -- Low_Bound + Length - 1.
0ac73189
AC
3467
3468 High_Bound :=
cc6f5d75
AC
3469 To_Ityp
3470 (Make_Op_Add (Loc,
3471 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
3472 Right_Opnd =>
3473 Make_Op_Subtract (Loc,
3474 Left_Opnd => New_Copy (Aggr_Length (NN)),
3475 Right_Opnd => Make_Artyp_Literal (1))));
0ac73189 3476
59262ebb 3477 -- Note that calculation of the high bound may cause overflow in some
bded454f
RD
3478 -- very weird cases, so in the general case we need an overflow check on
3479 -- the high bound. We can avoid this for the common case of string types
3480 -- and other types whose index is Positive, since we chose a wider range
3481 -- for the arithmetic type.
76c597a1 3482
59262ebb
AC
3483 if Istyp /= Standard_Positive then
3484 Activate_Overflow_Check (High_Bound);
3485 end if;
76c597a1
AC
3486
3487 -- Handle the exceptional case where the result is null, in which case
a29262fd
AC
3488 -- case the bounds come from the last operand (so that we get the proper
3489 -- bounds if the last operand is super-flat).
3490
0ac73189 3491 if Result_May_Be_Null then
88a27b18 3492 Low_Bound :=
9b16cb57 3493 Make_If_Expression (Loc,
88a27b18
AC
3494 Expressions => New_List (
3495 Make_Op_Eq (Loc,
3496 Left_Opnd => New_Copy (Aggr_Length (NN)),
3497 Right_Opnd => Make_Artyp_Literal (0)),
3498 Last_Opnd_Low_Bound,
3499 Low_Bound));
3500
0ac73189 3501 High_Bound :=
9b16cb57 3502 Make_If_Expression (Loc,
0ac73189
AC
3503 Expressions => New_List (
3504 Make_Op_Eq (Loc,
3505 Left_Opnd => New_Copy (Aggr_Length (NN)),
fa969310 3506 Right_Opnd => Make_Artyp_Literal (0)),
a29262fd 3507 Last_Opnd_High_Bound,
0ac73189
AC
3508 High_Bound));
3509 end if;
3510
d0f8d157
AC
3511 -- Here is where we insert the saved up actions
3512
3513 Insert_Actions (Cnode, Actions, Suppress => All_Checks);
3514
602a7ec0
AC
3515 -- Now we construct an array object with appropriate bounds. We mark
3516 -- the target as internal to prevent useless initialization when
e526d0c7
AC
3517 -- Initialize_Scalars is enabled. Also since this is the actual result
3518 -- entity, we make sure we have debug information for the result.
70482933 3519
191fcb3a 3520 Ent := Make_Temporary (Loc, 'S');
008f6fd3 3521 Set_Is_Internal (Ent);
e526d0c7 3522 Set_Needs_Debug_Info (Ent);
70482933 3523
76c597a1 3524 -- If the bound is statically known to be out of range, we do not want
fa969310
AC
3525 -- to abort, we want a warning and a runtime constraint error. Note that
3526 -- we have arranged that the result will not be treated as a static
3527 -- constant, so we won't get an illegality during this insertion.
76c597a1 3528
df46b832
AC
3529 Insert_Action (Cnode,
3530 Make_Object_Declaration (Loc,
3531 Defining_Identifier => Ent,
df46b832
AC
3532 Object_Definition =>
3533 Make_Subtype_Indication (Loc,
fdac1f80 3534 Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
df46b832
AC
3535 Constraint =>
3536 Make_Index_Or_Discriminant_Constraint (Loc,
3537 Constraints => New_List (
3538 Make_Range (Loc,
0ac73189
AC
3539 Low_Bound => Low_Bound,
3540 High_Bound => High_Bound))))),
df46b832
AC
3541 Suppress => All_Checks);
3542
d1f453b7
RD
3543 -- If the result of the concatenation appears as the initializing
3544 -- expression of an object declaration, we can just rename the
3545 -- result, rather than copying it.
3546
3547 Set_OK_To_Rename (Ent);
3548
76c597a1
AC
3549 -- Catch the static out of range case now
3550
3551 if Raises_Constraint_Error (High_Bound) then
3552 raise Concatenation_Error;
3553 end if;
3554
df46b832
AC
3555 -- Now we will generate the assignments to do the actual concatenation
3556
bded454f
RD
3557 -- There is one case in which we will not do this, namely when all the
3558 -- following conditions are met:
3559
3560 -- The result type is Standard.String
3561
3562 -- There are nine or fewer retained (non-null) operands
3563
ffec8e81 3564 -- The optimization level is -O0
bded454f
RD
3565
3566 -- The corresponding System.Concat_n.Str_Concat_n routine is
3567 -- available in the run time.
3568
3569 -- The debug flag gnatd.c is not set
3570
3571 -- If all these conditions are met then we generate a call to the
3572 -- relevant concatenation routine. The purpose of this is to avoid
3573 -- undesirable code bloat at -O0.
3574
3575 if Atyp = Standard_String
3576 and then NN in 2 .. 9
00ba7be8 3577 and then (Lib_Level_Target
62a64085 3578 or else ((Optimization_Level = 0 or else Debug_Flag_Dot_CC)
cc6f5d75 3579 and then not Debug_Flag_Dot_C))
bded454f
RD
3580 then
3581 declare
3582 RR : constant array (Nat range 2 .. 9) of RE_Id :=
3583 (RE_Str_Concat_2,
3584 RE_Str_Concat_3,
3585 RE_Str_Concat_4,
3586 RE_Str_Concat_5,
3587 RE_Str_Concat_6,
3588 RE_Str_Concat_7,
3589 RE_Str_Concat_8,
3590 RE_Str_Concat_9);
3591
3592 begin
3593 if RTE_Available (RR (NN)) then
3594 declare
3595 Opnds : constant List_Id :=
3596 New_List (New_Occurrence_Of (Ent, Loc));
3597
3598 begin
3599 for J in 1 .. NN loop
3600 if Is_List_Member (Operands (J)) then
3601 Remove (Operands (J));
3602 end if;
3603
3604 if Base_Type (Etype (Operands (J))) = Ctyp then
3605 Append_To (Opnds,
3606 Make_Aggregate (Loc,
3607 Component_Associations => New_List (
3608 Make_Component_Association (Loc,
3609 Choices => New_List (
3610 Make_Integer_Literal (Loc, 1)),
3611 Expression => Operands (J)))));
3612
3613 else
3614 Append_To (Opnds, Operands (J));
3615 end if;
3616 end loop;
3617
3618 Insert_Action (Cnode,
3619 Make_Procedure_Call_Statement (Loc,
e4494292 3620 Name => New_Occurrence_Of (RTE (RR (NN)), Loc),
bded454f
RD
3621 Parameter_Associations => Opnds));
3622
e4494292 3623 Result := New_Occurrence_Of (Ent, Loc);
bded454f
RD
3624 goto Done;
3625 end;
3626 end if;
3627 end;
3628 end if;
3629
3630 -- Not special case so generate the assignments
3631
76c597a1
AC
3632 Known_Non_Null_Operand_Seen := False;
3633
df46b832
AC
3634 for J in 1 .. NN loop
3635 declare
3636 Lo : constant Node_Id :=
3637 Make_Op_Add (Loc,
46ff89f3 3638 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
df46b832
AC
3639 Right_Opnd => Aggr_Length (J - 1));
3640
3641 Hi : constant Node_Id :=
3642 Make_Op_Add (Loc,
46ff89f3 3643 Left_Opnd => To_Artyp (New_Copy (Low_Bound)),
df46b832
AC
3644 Right_Opnd =>
3645 Make_Op_Subtract (Loc,
3646 Left_Opnd => Aggr_Length (J),
fa969310 3647 Right_Opnd => Make_Artyp_Literal (1)));
70482933 3648
df46b832 3649 begin
fdac1f80
AC
3650 -- Singleton case, simple assignment
3651
3652 if Base_Type (Etype (Operands (J))) = Ctyp then
76c597a1 3653 Known_Non_Null_Operand_Seen := True;
df46b832
AC
3654 Insert_Action (Cnode,
3655 Make_Assignment_Statement (Loc,
3656 Name =>
3657 Make_Indexed_Component (Loc,
3658 Prefix => New_Occurrence_Of (Ent, Loc),
fdac1f80 3659 Expressions => New_List (To_Ityp (Lo))),
df46b832
AC
3660 Expression => Operands (J)),
3661 Suppress => All_Checks);
70482933 3662
76c597a1
AC
3663 -- Array case, slice assignment, skipped when argument is fixed
3664 -- length and known to be null.
fdac1f80 3665
76c597a1
AC
3666 elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
3667 declare
3668 Assign : Node_Id :=
3669 Make_Assignment_Statement (Loc,
3670 Name =>
3671 Make_Slice (Loc,
3672 Prefix =>
3673 New_Occurrence_Of (Ent, Loc),
3674 Discrete_Range =>
3675 Make_Range (Loc,
3676 Low_Bound => To_Ityp (Lo),
3677 High_Bound => To_Ityp (Hi))),
3678 Expression => Operands (J));
3679 begin
3680 if Is_Fixed_Length (J) then
3681 Known_Non_Null_Operand_Seen := True;
3682
3683 elsif not Known_Non_Null_Operand_Seen then
3684
3685 -- Here if operand length is not statically known and no
3686 -- operand known to be non-null has been processed yet.
3687 -- If operand length is 0, we do not need to perform the
3688 -- assignment, and we must avoid the evaluation of the
3689 -- high bound of the slice, since it may underflow if the
3690 -- low bound is Ityp'First.
3691
3692 Assign :=
3693 Make_Implicit_If_Statement (Cnode,
39ade2f9 3694 Condition =>
76c597a1 3695 Make_Op_Ne (Loc,
39ade2f9 3696 Left_Opnd =>
76c597a1
AC
3697 New_Occurrence_Of (Var_Length (J), Loc),
3698 Right_Opnd => Make_Integer_Literal (Loc, 0)),
39ade2f9 3699 Then_Statements => New_List (Assign));
76c597a1 3700 end if;
fa969310 3701
76c597a1
AC
3702 Insert_Action (Cnode, Assign, Suppress => All_Checks);
3703 end;
df46b832
AC
3704 end if;
3705 end;
3706 end loop;
70482933 3707
0ac73189
AC
3708 -- Finally we build the result, which is a reference to the array object
3709
e4494292 3710 Result := New_Occurrence_Of (Ent, Loc);
70482933 3711
df46b832
AC
3712 <<Done>>
3713 Rewrite (Cnode, Result);
fdac1f80
AC
3714 Analyze_And_Resolve (Cnode, Atyp);
3715
3716 exception
3717 when Concatenation_Error =>
76c597a1
AC
3718
3719 -- Kill warning generated for the declaration of the static out of
3720 -- range high bound, and instead generate a Constraint_Error with
3721 -- an appropriate specific message.
3722
3723 Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
3724 Apply_Compile_Time_Constraint_Error
3725 (N => Cnode,
324ac540 3726 Msg => "concatenation result upper bound out of range??",
76c597a1 3727 Reason => CE_Range_Check_Failed);
fdac1f80 3728 end Expand_Concatenate;
70482933 3729
f6194278
RD
3730 ---------------------------------------------------
3731 -- Expand_Membership_Minimize_Eliminate_Overflow --
3732 ---------------------------------------------------
3733
3734 procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id) is
3735 pragma Assert (Nkind (N) = N_In);
3736 -- Despite the name, this routine applies only to N_In, not to
3737 -- N_Not_In. The latter is always rewritten as not (X in Y).
3738
71fb4dc8
AC
3739 Result_Type : constant Entity_Id := Etype (N);
3740 -- Capture result type, may be a derived boolean type
3741
b6b5cca8
AC
3742 Loc : constant Source_Ptr := Sloc (N);
3743 Lop : constant Node_Id := Left_Opnd (N);
3744 Rop : constant Node_Id := Right_Opnd (N);
3745
3746 -- Note: there are many referencs to Etype (Lop) and Etype (Rop). It
3747 -- is thus tempting to capture these values, but due to the rewrites
3748 -- that occur as a result of overflow checking, these values change
3749 -- as we go along, and it is safe just to always use Etype explicitly.
f6194278
RD
3750
3751 Restype : constant Entity_Id := Etype (N);
3752 -- Save result type
3753
3754 Lo, Hi : Uint;
d8192289 3755 -- Bounds in Minimize calls, not used currently
f6194278
RD
3756
3757 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
3758 -- Entity for Long_Long_Integer'Base (Standard should export this???)
3759
3760 begin
a7f1b24f 3761 Minimize_Eliminate_Overflows (Lop, Lo, Hi, Top_Level => False);
f6194278
RD
3762
3763 -- If right operand is a subtype name, and the subtype name has no
3764 -- predicate, then we can just replace the right operand with an
3765 -- explicit range T'First .. T'Last, and use the explicit range code.
3766
b6b5cca8
AC
3767 if Nkind (Rop) /= N_Range
3768 and then No (Predicate_Function (Etype (Rop)))
3769 then
3770 declare
3771 Rtyp : constant Entity_Id := Etype (Rop);
3772 begin
3773 Rewrite (Rop,
3774 Make_Range (Loc,
cc6f5d75 3775 Low_Bound =>
b6b5cca8
AC
3776 Make_Attribute_Reference (Loc,
3777 Attribute_Name => Name_First,
e4494292 3778 Prefix => New_Occurrence_Of (Rtyp, Loc)),
b6b5cca8
AC
3779 High_Bound =>
3780 Make_Attribute_Reference (Loc,
3781 Attribute_Name => Name_Last,
e4494292 3782 Prefix => New_Occurrence_Of (Rtyp, Loc))));
b6b5cca8
AC
3783 Analyze_And_Resolve (Rop, Rtyp, Suppress => All_Checks);
3784 end;
f6194278
RD
3785 end if;
3786
3787 -- Here for the explicit range case. Note that the bounds of the range
3788 -- have not been processed for minimized or eliminated checks.
3789
3790 if Nkind (Rop) = N_Range then
a7f1b24f 3791 Minimize_Eliminate_Overflows
b6b5cca8 3792 (Low_Bound (Rop), Lo, Hi, Top_Level => False);
a7f1b24f 3793 Minimize_Eliminate_Overflows
c7e152b5 3794 (High_Bound (Rop), Lo, Hi, Top_Level => False);
f6194278
RD
3795
3796 -- We have A in B .. C, treated as A >= B and then A <= C
3797
3798 -- Bignum case
3799
b6b5cca8 3800 if Is_RTE (Etype (Lop), RE_Bignum)
f6194278
RD
3801 or else Is_RTE (Etype (Low_Bound (Rop)), RE_Bignum)
3802 or else Is_RTE (Etype (High_Bound (Rop)), RE_Bignum)
3803 then
3804 declare
3805 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3806 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
71fb4dc8
AC
3807 L : constant Entity_Id :=
3808 Make_Defining_Identifier (Loc, Name_uL);
f6194278
RD
3809 Lopnd : constant Node_Id := Convert_To_Bignum (Lop);
3810 Lbound : constant Node_Id :=
3811 Convert_To_Bignum (Low_Bound (Rop));
3812 Hbound : constant Node_Id :=
3813 Convert_To_Bignum (High_Bound (Rop));
3814
71fb4dc8
AC
3815 -- Now we rewrite the membership test node to look like
3816
3817 -- do
3818 -- Bnn : Result_Type;
3819 -- declare
3820 -- M : Mark_Id := SS_Mark;
3821 -- L : Bignum := Lopnd;
3822 -- begin
3823 -- Bnn := Big_GE (L, Lbound) and then Big_LE (L, Hbound)
3824 -- SS_Release (M);
3825 -- end;
3826 -- in
3827 -- Bnn
3828 -- end
f6194278
RD
3829
3830 begin
71fb4dc8
AC
3831 -- Insert declaration of L into declarations of bignum block
3832
f6194278
RD
3833 Insert_After
3834 (Last (Declarations (Blk)),
3835 Make_Object_Declaration (Loc,
71fb4dc8 3836 Defining_Identifier => L,
f6194278
RD
3837 Object_Definition =>
3838 New_Occurrence_Of (RTE (RE_Bignum), Loc),
3839 Expression => Lopnd));
3840
71fb4dc8
AC
3841 -- Insert assignment to Bnn into expressions of bignum block
3842
f6194278
RD
3843 Insert_Before
3844 (First (Statements (Handled_Statement_Sequence (Blk))),
3845 Make_Assignment_Statement (Loc,
3846 Name => New_Occurrence_Of (Bnn, Loc),
3847 Expression =>
3848 Make_And_Then (Loc,
cc6f5d75 3849 Left_Opnd =>
f6194278
RD
3850 Make_Function_Call (Loc,
3851 Name =>
3852 New_Occurrence_Of (RTE (RE_Big_GE), Loc),
71fb4dc8
AC
3853 Parameter_Associations => New_List (
3854 New_Occurrence_Of (L, Loc),
3855 Lbound)),
cc6f5d75 3856
f6194278
RD
3857 Right_Opnd =>
3858 Make_Function_Call (Loc,
3859 Name =>
71fb4dc8
AC
3860 New_Occurrence_Of (RTE (RE_Big_LE), Loc),
3861 Parameter_Associations => New_List (
3862 New_Occurrence_Of (L, Loc),
3863 Hbound)))));
f6194278 3864
71fb4dc8 3865 -- Now rewrite the node
f6194278 3866
71fb4dc8
AC
3867 Rewrite (N,
3868 Make_Expression_With_Actions (Loc,
3869 Actions => New_List (
3870 Make_Object_Declaration (Loc,
3871 Defining_Identifier => Bnn,
3872 Object_Definition =>
3873 New_Occurrence_Of (Result_Type, Loc)),
3874 Blk),
3875 Expression => New_Occurrence_Of (Bnn, Loc)));
3876 Analyze_And_Resolve (N, Result_Type);
f6194278
RD
3877 return;
3878 end;
3879
3880 -- Here if no bignums around
3881
3882 else
3883 -- Case where types are all the same
3884
b6b5cca8 3885 if Base_Type (Etype (Lop)) = Base_Type (Etype (Low_Bound (Rop)))
f6194278 3886 and then
b6b5cca8 3887 Base_Type (Etype (Lop)) = Base_Type (Etype (High_Bound (Rop)))
f6194278
RD
3888 then
3889 null;
3890
3891 -- If types are not all the same, it means that we have rewritten
3892 -- at least one of them to be of type Long_Long_Integer, and we
3893 -- will convert the other operands to Long_Long_Integer.
3894
3895 else
3896 Convert_To_And_Rewrite (LLIB, Lop);
71fb4dc8
AC
3897 Set_Analyzed (Lop, False);
3898 Analyze_And_Resolve (Lop, LLIB);
3899
3900 -- For the right operand, avoid unnecessary recursion into
3901 -- this routine, we know that overflow is not possible.
f6194278
RD
3902
3903 Convert_To_And_Rewrite (LLIB, Low_Bound (Rop));
3904 Convert_To_And_Rewrite (LLIB, High_Bound (Rop));
3905 Set_Analyzed (Rop, False);
71fb4dc8 3906 Analyze_And_Resolve (Rop, LLIB, Suppress => Overflow_Check);
f6194278
RD
3907 end if;
3908
3909 -- Now the three operands are of the same signed integer type,
b6b5cca8
AC
3910 -- so we can use the normal expansion routine for membership,
3911 -- setting the flag to prevent recursion into this procedure.
f6194278
RD
3912
3913 Set_No_Minimize_Eliminate (N);
3914 Expand_N_In (N);
3915 end if;
3916
3917 -- Right operand is a subtype name and the subtype has a predicate. We
f6636994
AC
3918 -- have to make sure the predicate is checked, and for that we need to
3919 -- use the standard N_In circuitry with appropriate types.
f6194278
RD
3920
3921 else
b6b5cca8 3922 pragma Assert (Present (Predicate_Function (Etype (Rop))));
f6194278
RD
3923
3924 -- If types are "right", just call Expand_N_In preventing recursion
3925
b6b5cca8 3926 if Base_Type (Etype (Lop)) = Base_Type (Etype (Rop)) then
f6194278
RD
3927 Set_No_Minimize_Eliminate (N);
3928 Expand_N_In (N);
3929
3930 -- Bignum case
3931
b6b5cca8 3932 elsif Is_RTE (Etype (Lop), RE_Bignum) then
f6194278 3933
71fb4dc8 3934 -- For X in T, we want to rewrite our node as
f6194278 3935
71fb4dc8
AC
3936 -- do
3937 -- Bnn : Result_Type;
f6194278 3938
71fb4dc8
AC
3939 -- declare
3940 -- M : Mark_Id := SS_Mark;
3941 -- Lnn : Long_Long_Integer'Base
3942 -- Nnn : Bignum;
f6194278 3943
71fb4dc8
AC
3944 -- begin
3945 -- Nnn := X;
3946
3947 -- if not Bignum_In_LLI_Range (Nnn) then
3948 -- Bnn := False;
3949 -- else
3950 -- Lnn := From_Bignum (Nnn);
3951 -- Bnn :=
3952 -- Lnn in LLIB (T'Base'First) .. LLIB (T'Base'Last)
3953 -- and then T'Base (Lnn) in T;
3954 -- end if;
cc6f5d75
AC
3955
3956 -- SS_Release (M);
71fb4dc8
AC
3957 -- end
3958 -- in
3959 -- Bnn
3960 -- end
f6194278 3961
f6636994 3962 -- A bit gruesome, but there doesn't seem to be a simpler way
f6194278
RD
3963
3964 declare
b6b5cca8
AC
3965 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3966 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
3967 Lnn : constant Entity_Id := Make_Temporary (Loc, 'L', N);
3968 Nnn : constant Entity_Id := Make_Temporary (Loc, 'N', N);
71fb4dc8
AC
3969 T : constant Entity_Id := Etype (Rop);
3970 TB : constant Entity_Id := Base_Type (T);
b6b5cca8 3971 Nin : Node_Id;
f6194278
RD
3972
3973 begin
71fb4dc8 3974 -- Mark the last membership operation to prevent recursion
f6194278
RD
3975
3976 Nin :=
3977 Make_In (Loc,
f6636994
AC
3978 Left_Opnd => Convert_To (TB, New_Occurrence_Of (Lnn, Loc)),
3979 Right_Opnd => New_Occurrence_Of (T, Loc));
f6194278
RD
3980 Set_No_Minimize_Eliminate (Nin);
3981
3982 -- Now decorate the block
3983
3984 Insert_After
3985 (Last (Declarations (Blk)),
3986 Make_Object_Declaration (Loc,
3987 Defining_Identifier => Lnn,
3988 Object_Definition => New_Occurrence_Of (LLIB, Loc)));
3989
3990 Insert_After
3991 (Last (Declarations (Blk)),
3992 Make_Object_Declaration (Loc,
3993 Defining_Identifier => Nnn,
3994 Object_Definition =>
3995 New_Occurrence_Of (RTE (RE_Bignum), Loc)));
3996
3997 Insert_List_Before
3998 (First (Statements (Handled_Statement_Sequence (Blk))),
3999 New_List (
4000 Make_Assignment_Statement (Loc,
4001 Name => New_Occurrence_Of (Nnn, Loc),
4002 Expression => Relocate_Node (Lop)),
4003
8b1011c0 4004 Make_Implicit_If_Statement (N,
f6194278 4005 Condition =>
71fb4dc8
AC
4006 Make_Op_Not (Loc,
4007 Right_Opnd =>
4008 Make_Function_Call (Loc,
4009 Name =>
4010 New_Occurrence_Of
4011 (RTE (RE_Bignum_In_LLI_Range), Loc),
4012 Parameter_Associations => New_List (
4013 New_Occurrence_Of (Nnn, Loc)))),
f6194278
RD
4014
4015 Then_Statements => New_List (
4016 Make_Assignment_Statement (Loc,
4017 Name => New_Occurrence_Of (Bnn, Loc),
4018 Expression =>
4019 New_Occurrence_Of (Standard_False, Loc))),
4020
4021 Else_Statements => New_List (
4022 Make_Assignment_Statement (Loc,
4023 Name => New_Occurrence_Of (Lnn, Loc),
4024 Expression =>
4025 Make_Function_Call (Loc,
4026 Name =>
4027 New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
4028 Parameter_Associations => New_List (
4029 New_Occurrence_Of (Nnn, Loc)))),
4030
4031 Make_Assignment_Statement (Loc,
71fb4dc8 4032 Name => New_Occurrence_Of (Bnn, Loc),
f6194278
RD
4033 Expression =>
4034 Make_And_Then (Loc,
71fb4dc8 4035 Left_Opnd =>
f6194278 4036 Make_In (Loc,
71fb4dc8 4037 Left_Opnd => New_Occurrence_Of (Lnn, Loc),
f6194278 4038 Right_Opnd =>
71fb4dc8
AC
4039 Make_Range (Loc,
4040 Low_Bound =>
4041 Convert_To (LLIB,
4042 Make_Attribute_Reference (Loc,
4043 Attribute_Name => Name_First,
4044 Prefix =>
4045 New_Occurrence_Of (TB, Loc))),
4046
4047 High_Bound =>
4048 Convert_To (LLIB,
4049 Make_Attribute_Reference (Loc,
4050 Attribute_Name => Name_Last,
4051 Prefix =>
4052 New_Occurrence_Of (TB, Loc))))),
4053
f6194278
RD
4054 Right_Opnd => Nin))))));
4055
71fb4dc8 4056 -- Now we can do the rewrite
f6194278 4057
71fb4dc8
AC
4058 Rewrite (N,
4059 Make_Expression_With_Actions (Loc,
4060 Actions => New_List (
4061 Make_Object_Declaration (Loc,
4062 Defining_Identifier => Bnn,
4063 Object_Definition =>
4064 New_Occurrence_Of (Result_Type, Loc)),
4065 Blk),
4066 Expression => New_Occurrence_Of (Bnn, Loc)));
4067 Analyze_And_Resolve (N, Result_Type);
f6194278
RD
4068 return;
4069 end;
4070
4071 -- Not bignum case, but types don't match (this means we rewrote the
b6b5cca8 4072 -- left operand to be Long_Long_Integer).
f6194278
RD
4073
4074 else
b6b5cca8 4075 pragma Assert (Base_Type (Etype (Lop)) = LLIB);
f6194278 4076
71fb4dc8
AC
4077 -- We rewrite the membership test as (where T is the type with
4078 -- the predicate, i.e. the type of the right operand)
f6194278 4079
71fb4dc8
AC
4080 -- Lop in LLIB (T'Base'First) .. LLIB (T'Base'Last)
4081 -- and then T'Base (Lop) in T
f6194278
RD
4082
4083 declare
71fb4dc8
AC
4084 T : constant Entity_Id := Etype (Rop);
4085 TB : constant Entity_Id := Base_Type (T);
f6194278
RD
4086 Nin : Node_Id;
4087
4088 begin
4089 -- The last membership test is marked to prevent recursion
4090
4091 Nin :=
4092 Make_In (Loc,
71fb4dc8
AC
4093 Left_Opnd => Convert_To (TB, Duplicate_Subexpr (Lop)),
4094 Right_Opnd => New_Occurrence_Of (T, Loc));
f6194278
RD
4095 Set_No_Minimize_Eliminate (Nin);
4096
4097 -- Now do the rewrite
4098
4099 Rewrite (N,
4100 Make_And_Then (Loc,
71fb4dc8 4101 Left_Opnd =>
f6194278
RD
4102 Make_In (Loc,
4103 Left_Opnd => Lop,
4104 Right_Opnd =>
71fb4dc8
AC
4105 Make_Range (Loc,
4106 Low_Bound =>
4107 Convert_To (LLIB,
4108 Make_Attribute_Reference (Loc,
4109 Attribute_Name => Name_First,
cc6f5d75
AC
4110 Prefix =>
4111 New_Occurrence_Of (TB, Loc))),
71fb4dc8
AC
4112 High_Bound =>
4113 Convert_To (LLIB,
4114 Make_Attribute_Reference (Loc,
4115 Attribute_Name => Name_Last,
cc6f5d75
AC
4116 Prefix =>
4117 New_Occurrence_Of (TB, Loc))))),
f6194278 4118 Right_Opnd => Nin));
71fb4dc8
AC
4119 Set_Analyzed (N, False);
4120 Analyze_And_Resolve (N, Restype);
f6194278
RD
4121 end;
4122 end if;
4123 end if;
4124 end Expand_Membership_Minimize_Eliminate_Overflow;
4125
70482933
RK
4126 ------------------------
4127 -- Expand_N_Allocator --
4128 ------------------------
4129
4130 procedure Expand_N_Allocator (N : Node_Id) is
8b1011c0
AC
4131 Etyp : constant Entity_Id := Etype (Expression (N));
4132 Loc : constant Source_Ptr := Sloc (N);
4133 PtrT : constant Entity_Id := Etype (N);
70482933 4134
26bff3d9
JM
4135 procedure Rewrite_Coextension (N : Node_Id);
4136 -- Static coextensions have the same lifetime as the entity they
8fc789c8 4137 -- constrain. Such occurrences can be rewritten as aliased objects
26bff3d9 4138 -- and their unrestricted access used instead of the coextension.
0669bebe 4139
8aec446b 4140 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id;
507ed3fd
AC
4141 -- Given a constrained array type E, returns a node representing the
4142 -- code to compute the size in storage elements for the given type.
205c14b0 4143 -- This is done without using the attribute (which malfunctions for
507ed3fd 4144 -- large sizes ???)
8aec446b 4145
26bff3d9
JM
4146 -------------------------
4147 -- Rewrite_Coextension --
4148 -------------------------
4149
4150 procedure Rewrite_Coextension (N : Node_Id) is
e5a22243
AC
4151 Temp_Id : constant Node_Id := Make_Temporary (Loc, 'C');
4152 Temp_Decl : Node_Id;
26bff3d9 4153
df3e68b1 4154 begin
26bff3d9
JM
4155 -- Generate:
4156 -- Cnn : aliased Etyp;
4157
df3e68b1
HK
4158 Temp_Decl :=
4159 Make_Object_Declaration (Loc,
4160 Defining_Identifier => Temp_Id,
243cae0a
AC
4161 Aliased_Present => True,
4162 Object_Definition => New_Occurrence_Of (Etyp, Loc));
26bff3d9 4163
26bff3d9 4164 if Nkind (Expression (N)) = N_Qualified_Expression then
df3e68b1 4165 Set_Expression (Temp_Decl, Expression (Expression (N)));
0669bebe 4166 end if;
26bff3d9 4167
e5a22243 4168 Insert_Action (N, Temp_Decl);
26bff3d9
JM
4169 Rewrite (N,
4170 Make_Attribute_Reference (Loc,
243cae0a 4171 Prefix => New_Occurrence_Of (Temp_Id, Loc),
26bff3d9
JM
4172 Attribute_Name => Name_Unrestricted_Access));
4173
4174 Analyze_And_Resolve (N, PtrT);
4175 end Rewrite_Coextension;
0669bebe 4176
8aec446b
AC
4177 ------------------------------
4178 -- Size_In_Storage_Elements --
4179 ------------------------------
4180
4181 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id is
4182 begin
4183 -- Logically this just returns E'Max_Size_In_Storage_Elements.
4184 -- However, the reason for the existence of this function is
4185 -- to construct a test for sizes too large, which means near the
4186 -- 32-bit limit on a 32-bit machine, and precisely the trouble
4187 -- is that we get overflows when sizes are greater than 2**31.
4188
507ed3fd 4189 -- So what we end up doing for array types is to use the expression:
8aec446b
AC
4190
4191 -- number-of-elements * component_type'Max_Size_In_Storage_Elements
4192
46202729 4193 -- which avoids this problem. All this is a bit bogus, but it does
8aec446b
AC
4194 -- mean we catch common cases of trying to allocate arrays that
4195 -- are too large, and which in the absence of a check results in
4196 -- undetected chaos ???
4197
ce532f42
AC
4198 -- Note in particular that this is a pessimistic estimate in the
4199 -- case of packed array types, where an array element might occupy
4200 -- just a fraction of a storage element???
4201
507ed3fd
AC
4202 declare
4203 Len : Node_Id;
4204 Res : Node_Id;
8aec446b 4205
507ed3fd
AC
4206 begin
4207 for J in 1 .. Number_Dimensions (E) loop
4208 Len :=
4209 Make_Attribute_Reference (Loc,
4210 Prefix => New_Occurrence_Of (E, Loc),
4211 Attribute_Name => Name_Length,
243cae0a 4212 Expressions => New_List (Make_Integer_Literal (Loc, J)));
8aec446b 4213
507ed3fd
AC
4214 if J = 1 then
4215 Res := Len;
8aec446b 4216
507ed3fd
AC
4217 else
4218 Res :=
4219 Make_Op_Multiply (Loc,
4220 Left_Opnd => Res,
4221 Right_Opnd => Len);
4222 end if;
4223 end loop;
8aec446b 4224
8aec446b 4225 return
507ed3fd
AC
4226 Make_Op_Multiply (Loc,
4227 Left_Opnd => Len,
4228 Right_Opnd =>
4229 Make_Attribute_Reference (Loc,
4230 Prefix => New_Occurrence_Of (Component_Type (E), Loc),
4231 Attribute_Name => Name_Max_Size_In_Storage_Elements));
4232 end;
8aec446b
AC
4233 end Size_In_Storage_Elements;
4234
8b1011c0
AC
4235 -- Local variables
4236
70861157 4237 Dtyp : constant Entity_Id := Available_View (Designated_Type (PtrT));
8b1011c0
AC
4238 Desig : Entity_Id;
4239 Nod : Node_Id;
4240 Pool : Entity_Id;
4241 Rel_Typ : Entity_Id;
4242 Temp : Entity_Id;
4243
0669bebe
GB
4244 -- Start of processing for Expand_N_Allocator
4245
70482933
RK
4246 begin
4247 -- RM E.2.3(22). We enforce that the expected type of an allocator
4248 -- shall not be a remote access-to-class-wide-limited-private type
4249
4250 -- Why is this being done at expansion time, seems clearly wrong ???
4251
4252 Validate_Remote_Access_To_Class_Wide_Type (N);
4253
ca5af305
AC
4254 -- Processing for anonymous access-to-controlled types. These access
4255 -- types receive a special finalization master which appears in the
4256 -- declarations of the enclosing semantic unit. This expansion is done
84f4072a
JM
4257 -- now to ensure that any additional types generated by this routine or
4258 -- Expand_Allocator_Expression inherit the proper type attributes.
ca5af305 4259
84f4072a 4260 if (Ekind (PtrT) = E_Anonymous_Access_Type
533369aa 4261 or else (Is_Itype (PtrT) and then No (Finalization_Master (PtrT))))
ca5af305
AC
4262 and then Needs_Finalization (Dtyp)
4263 then
8b1011c0
AC
4264 -- Detect the allocation of an anonymous controlled object where the
4265 -- type of the context is named. For example:
4266
4267 -- procedure Proc (Ptr : Named_Access_Typ);
4268 -- Proc (new Designated_Typ);
4269
4270 -- Regardless of the anonymous-to-named access type conversion, the
4271 -- lifetime of the object must be associated with the named access
0088ba92 4272 -- type. Use the finalization-related attributes of this type.
8b1011c0
AC
4273
4274 if Nkind_In (Parent (N), N_Type_Conversion,
4275 N_Unchecked_Type_Conversion)
4276 and then Ekind_In (Etype (Parent (N)), E_Access_Subtype,
4277 E_Access_Type,
4278 E_General_Access_Type)
4279 then
4280 Rel_Typ := Etype (Parent (N));
4281 else
4282 Rel_Typ := Empty;
4283 end if;
4284
b254da66
AC
4285 -- Anonymous access-to-controlled types allocate on the global pool.
4286 -- Do not set this attribute on .NET/JVM since those targets do not
24d4b3d5 4287 -- support pools. Note that this is a "root type only" attribute.
ca5af305 4288
bde73c6b 4289 if No (Associated_Storage_Pool (PtrT)) and then VM_Target = No_VM then
8b1011c0 4290 if Present (Rel_Typ) then
7a5b62b0 4291 Set_Associated_Storage_Pool
24d4b3d5 4292 (Root_Type (PtrT), Associated_Storage_Pool (Rel_Typ));
8b1011c0 4293 else
7a5b62b0 4294 Set_Associated_Storage_Pool
24d4b3d5 4295 (Root_Type (PtrT), RTE (RE_Global_Pool_Object));
8b1011c0 4296 end if;
ca5af305
AC
4297 end if;
4298
4299 -- The finalization master must be inserted and analyzed as part of
5114f3ff 4300 -- the current semantic unit. Note that the master is updated when
24d4b3d5
AC
4301 -- analysis changes current units. Note that this is a "root type
4302 -- only" attribute.
ca5af305 4303
5114f3ff 4304 if Present (Rel_Typ) then
24d4b3d5
AC
4305 Set_Finalization_Master
4306 (Root_Type (PtrT), Finalization_Master (Rel_Typ));
5114f3ff 4307 else
24d4b3d5
AC
4308 Set_Finalization_Master
4309 (Root_Type (PtrT), Current_Anonymous_Master);
ca5af305
AC
4310 end if;
4311 end if;
4312
4313 -- Set the storage pool and find the appropriate version of Allocate to
8417f4b2
AC
4314 -- call. Do not overwrite the storage pool if it is already set, which
4315 -- can happen for build-in-place function returns (see
200b7162 4316 -- Exp_Ch4.Expand_N_Extended_Return_Statement).
70482933 4317
200b7162
BD
4318 if No (Storage_Pool (N)) then
4319 Pool := Associated_Storage_Pool (Root_Type (PtrT));
70482933 4320
200b7162
BD
4321 if Present (Pool) then
4322 Set_Storage_Pool (N, Pool);
fbf5a39b 4323
200b7162
BD
4324 if Is_RTE (Pool, RE_SS_Pool) then
4325 if VM_Target = No_VM then
4326 Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
4327 end if;
fbf5a39b 4328
a8551b5f
AC
4329 -- In the case of an allocator for a simple storage pool, locate
4330 -- and save a reference to the pool type's Allocate routine.
4331
4332 elsif Present (Get_Rep_Pragma
f6205414 4333 (Etype (Pool), Name_Simple_Storage_Pool_Type))
a8551b5f
AC
4334 then
4335 declare
a8551b5f 4336 Pool_Type : constant Entity_Id := Base_Type (Etype (Pool));
260359e3 4337 Alloc_Op : Entity_Id;
a8551b5f 4338 begin
260359e3 4339 Alloc_Op := Get_Name_Entity_Id (Name_Allocate);
a8551b5f
AC
4340 while Present (Alloc_Op) loop
4341 if Scope (Alloc_Op) = Scope (Pool_Type)
4342 and then Present (First_Formal (Alloc_Op))
4343 and then Etype (First_Formal (Alloc_Op)) = Pool_Type
4344 then
4345 Set_Procedure_To_Call (N, Alloc_Op);
a8551b5f 4346 exit;
260359e3
AC
4347 else
4348 Alloc_Op := Homonym (Alloc_Op);
a8551b5f 4349 end if;
a8551b5f
AC
4350 end loop;
4351 end;
4352
200b7162
BD
4353 elsif Is_Class_Wide_Type (Etype (Pool)) then
4354 Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
4355
4356 else
4357 Set_Procedure_To_Call (N,
4358 Find_Prim_Op (Etype (Pool), Name_Allocate));
4359 end if;
70482933
RK
4360 end if;
4361 end if;
4362
685094bf
RD
4363 -- Under certain circumstances we can replace an allocator by an access
4364 -- to statically allocated storage. The conditions, as noted in AARM
4365 -- 3.10 (10c) are as follows:
70482933
RK
4366
4367 -- Size and initial value is known at compile time
4368 -- Access type is access-to-constant
4369
fbf5a39b
AC
4370 -- The allocator is not part of a constraint on a record component,
4371 -- because in that case the inserted actions are delayed until the
4372 -- record declaration is fully analyzed, which is too late for the
4373 -- analysis of the rewritten allocator.
4374
70482933
RK
4375 if Is_Access_Constant (PtrT)
4376 and then Nkind (Expression (N)) = N_Qualified_Expression
4377 and then Compile_Time_Known_Value (Expression (Expression (N)))
243cae0a
AC
4378 and then Size_Known_At_Compile_Time
4379 (Etype (Expression (Expression (N))))
fbf5a39b 4380 and then not Is_Record_Type (Current_Scope)
70482933
RK
4381 then
4382 -- Here we can do the optimization. For the allocator
4383
4384 -- new x'(y)
4385
4386 -- We insert an object declaration
4387
4388 -- Tnn : aliased x := y;
4389
685094bf
RD
4390 -- and replace the allocator by Tnn'Unrestricted_Access. Tnn is
4391 -- marked as requiring static allocation.
70482933 4392
df3e68b1 4393 Temp := Make_Temporary (Loc, 'T', Expression (Expression (N)));
70482933
RK
4394 Desig := Subtype_Mark (Expression (N));
4395
4396 -- If context is constrained, use constrained subtype directly,
8fc789c8 4397 -- so that the constant is not labelled as having a nominally
70482933
RK
4398 -- unconstrained subtype.
4399
0da2c8ac
AC
4400 if Entity (Desig) = Base_Type (Dtyp) then
4401 Desig := New_Occurrence_Of (Dtyp, Loc);
70482933
RK
4402 end if;
4403
4404 Insert_Action (N,
4405 Make_Object_Declaration (Loc,
4406 Defining_Identifier => Temp,
4407 Aliased_Present => True,
4408 Constant_Present => Is_Access_Constant (PtrT),
4409 Object_Definition => Desig,
4410 Expression => Expression (Expression (N))));
4411
4412 Rewrite (N,
4413 Make_Attribute_Reference (Loc,
243cae0a 4414 Prefix => New_Occurrence_Of (Temp, Loc),
70482933
RK
4415 Attribute_Name => Name_Unrestricted_Access));
4416
4417 Analyze_And_Resolve (N, PtrT);
4418
685094bf 4419 -- We set the variable as statically allocated, since we don't want
a90bd866 4420 -- it going on the stack of the current procedure.
70482933
RK
4421
4422 Set_Is_Statically_Allocated (Temp);
4423 return;
4424 end if;
4425
0669bebe
GB
4426 -- Same if the allocator is an access discriminant for a local object:
4427 -- instead of an allocator we create a local value and constrain the
308e6f3a 4428 -- enclosing object with the corresponding access attribute.
0669bebe 4429
26bff3d9
JM
4430 if Is_Static_Coextension (N) then
4431 Rewrite_Coextension (N);
0669bebe
GB
4432 return;
4433 end if;
4434
8aec446b
AC
4435 -- Check for size too large, we do this because the back end misses
4436 -- proper checks here and can generate rubbish allocation calls when
4437 -- we are near the limit. We only do this for the 32-bit address case
4438 -- since that is from a practical point of view where we see a problem.
4439
4440 if System_Address_Size = 32
4441 and then not Storage_Checks_Suppressed (PtrT)
4442 and then not Storage_Checks_Suppressed (Dtyp)
4443 and then not Storage_Checks_Suppressed (Etyp)
4444 then
4445 -- The check we want to generate should look like
4446
4447 -- if Etyp'Max_Size_In_Storage_Elements > 3.5 gigabytes then
4448 -- raise Storage_Error;
4449 -- end if;
4450
308e6f3a 4451 -- where 3.5 gigabytes is a constant large enough to accommodate any
507ed3fd
AC
4452 -- reasonable request for. But we can't do it this way because at
4453 -- least at the moment we don't compute this attribute right, and
4454 -- can silently give wrong results when the result gets large. Since
4455 -- this is all about large results, that's bad, so instead we only
205c14b0 4456 -- apply the check for constrained arrays, and manually compute the
507ed3fd 4457 -- value of the attribute ???
8aec446b 4458
507ed3fd
AC
4459 if Is_Array_Type (Etyp) and then Is_Constrained (Etyp) then
4460 Insert_Action (N,
4461 Make_Raise_Storage_Error (Loc,
4462 Condition =>
4463 Make_Op_Gt (Loc,
4464 Left_Opnd => Size_In_Storage_Elements (Etyp),
4465 Right_Opnd =>
243cae0a 4466 Make_Integer_Literal (Loc, Uint_7 * (Uint_2 ** 29))),
507ed3fd
AC
4467 Reason => SE_Object_Too_Large));
4468 end if;
8aec446b
AC
4469 end if;
4470
b3b26ace
AC
4471 -- If no storage pool has been specified and we have the restriction
4472 -- No_Standard_Allocators_After_Elaboration is present, then generate
4473 -- a call to Elaboration_Allocators.Check_Standard_Allocator.
4474
4475 if Nkind (N) = N_Allocator
4476 and then No (Storage_Pool (N))
4477 and then Restriction_Active (No_Standard_Allocators_After_Elaboration)
4478 then
4479 Insert_Action (N,
4480 Make_Procedure_Call_Statement (Loc,
4481 Name =>
4482 New_Occurrence_Of (RTE (RE_Check_Standard_Allocator), Loc)));
4483 end if;
4484
0da2c8ac 4485 -- Handle case of qualified expression (other than optimization above)
cac5a801
AC
4486 -- First apply constraint checks, because the bounds or discriminants
4487 -- in the aggregate might not match the subtype mark in the allocator.
0da2c8ac 4488
70482933 4489 if Nkind (Expression (N)) = N_Qualified_Expression then
cac5a801
AC
4490 Apply_Constraint_Check
4491 (Expression (Expression (N)), Etype (Expression (N)));
4492
fbf5a39b 4493 Expand_Allocator_Expression (N);
26bff3d9
JM
4494 return;
4495 end if;
fbf5a39b 4496
26bff3d9
JM
4497 -- If the allocator is for a type which requires initialization, and
4498 -- there is no initial value (i.e. operand is a subtype indication
685094bf
RD
4499 -- rather than a qualified expression), then we must generate a call to
4500 -- the initialization routine using an expressions action node:
70482933 4501
26bff3d9 4502 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
70482933 4503
26bff3d9
JM
4504 -- Here ptr_T is the pointer type for the allocator, and T is the
4505 -- subtype of the allocator. A special case arises if the designated
4506 -- type of the access type is a task or contains tasks. In this case
4507 -- the call to Init (Temp.all ...) is replaced by code that ensures
4508 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
6be44a9a 4509 -- for details). In addition, if the type T is a task type, then the
26bff3d9 4510 -- first argument to Init must be converted to the task record type.
70482933 4511
26bff3d9 4512 declare
df3e68b1
HK
4513 T : constant Entity_Id := Entity (Expression (N));
4514 Args : List_Id;
4515 Decls : List_Id;
4516 Decl : Node_Id;
4517 Discr : Elmt_Id;
4518 Init : Entity_Id;
4519 Init_Arg1 : Node_Id;
4520 Temp_Decl : Node_Id;
4521 Temp_Type : Entity_Id;
70482933 4522
26bff3d9
JM
4523 begin
4524 if No_Initialization (N) then
df3e68b1
HK
4525
4526 -- Even though this might be a simple allocation, create a custom
deb8dacc
HK
4527 -- Allocate if the context requires it. Since .NET/JVM compilers
4528 -- do not support pools, this step is skipped.
df3e68b1 4529
deb8dacc 4530 if VM_Target = No_VM
d3f70b35 4531 and then Present (Finalization_Master (PtrT))
deb8dacc 4532 then
df3e68b1 4533 Build_Allocate_Deallocate_Proc
ca5af305 4534 (N => N,
df3e68b1
HK
4535 Is_Allocate => True);
4536 end if;
70482933 4537
26bff3d9 4538 -- Case of no initialization procedure present
70482933 4539
26bff3d9 4540 elsif not Has_Non_Null_Base_Init_Proc (T) then
70482933 4541
26bff3d9 4542 -- Case of simple initialization required
70482933 4543
26bff3d9 4544 if Needs_Simple_Initialization (T) then
b4592168 4545 Check_Restriction (No_Default_Initialization, N);
26bff3d9
JM
4546 Rewrite (Expression (N),
4547 Make_Qualified_Expression (Loc,
4548 Subtype_Mark => New_Occurrence_Of (T, Loc),
b4592168 4549 Expression => Get_Simple_Init_Val (T, N)));
70482933 4550
26bff3d9
JM
4551 Analyze_And_Resolve (Expression (Expression (N)), T);
4552 Analyze_And_Resolve (Expression (N), T);
4553 Set_Paren_Count (Expression (Expression (N)), 1);
4554 Expand_N_Allocator (N);
70482933 4555
26bff3d9 4556 -- No initialization required
70482933
RK
4557
4558 else
26bff3d9
JM
4559 null;
4560 end if;
70482933 4561
26bff3d9 4562 -- Case of initialization procedure present, must be called
70482933 4563
26bff3d9 4564 else
b4592168 4565 Check_Restriction (No_Default_Initialization, N);
70482933 4566
b4592168
GD
4567 if not Restriction_Active (No_Default_Initialization) then
4568 Init := Base_Init_Proc (T);
4569 Nod := N;
191fcb3a 4570 Temp := Make_Temporary (Loc, 'P');
70482933 4571
b4592168 4572 -- Construct argument list for the initialization routine call
70482933 4573
df3e68b1 4574 Init_Arg1 :=
b4592168 4575 Make_Explicit_Dereference (Loc,
df3e68b1 4576 Prefix =>
e4494292 4577 New_Occurrence_Of (Temp, Loc));
df3e68b1
HK
4578
4579 Set_Assignment_OK (Init_Arg1);
b4592168 4580 Temp_Type := PtrT;
26bff3d9 4581
b4592168
GD
4582 -- The initialization procedure expects a specific type. if the
4583 -- context is access to class wide, indicate that the object
4584 -- being allocated has the right specific type.
70482933 4585
b4592168 4586 if Is_Class_Wide_Type (Dtyp) then
df3e68b1 4587 Init_Arg1 := Unchecked_Convert_To (T, Init_Arg1);
b4592168 4588 end if;
70482933 4589
b4592168
GD
4590 -- If designated type is a concurrent type or if it is private
4591 -- type whose definition is a concurrent type, the first
4592 -- argument in the Init routine has to be unchecked conversion
4593 -- to the corresponding record type. If the designated type is
243cae0a 4594 -- a derived type, also convert the argument to its root type.
20b5d666 4595
b4592168 4596 if Is_Concurrent_Type (T) then
df3e68b1
HK
4597 Init_Arg1 :=
4598 Unchecked_Convert_To (
4599 Corresponding_Record_Type (T), Init_Arg1);
70482933 4600
b4592168
GD
4601 elsif Is_Private_Type (T)
4602 and then Present (Full_View (T))
4603 and then Is_Concurrent_Type (Full_View (T))
4604 then
df3e68b1 4605 Init_Arg1 :=
b4592168 4606 Unchecked_Convert_To
df3e68b1 4607 (Corresponding_Record_Type (Full_View (T)), Init_Arg1);
70482933 4608
b4592168
GD
4609 elsif Etype (First_Formal (Init)) /= Base_Type (T) then
4610 declare
4611 Ftyp : constant Entity_Id := Etype (First_Formal (Init));
df3e68b1 4612
b4592168 4613 begin
df3e68b1
HK
4614 Init_Arg1 := OK_Convert_To (Etype (Ftyp), Init_Arg1);
4615 Set_Etype (Init_Arg1, Ftyp);
b4592168
GD
4616 end;
4617 end if;
70482933 4618
df3e68b1 4619 Args := New_List (Init_Arg1);
70482933 4620
b4592168
GD
4621 -- For the task case, pass the Master_Id of the access type as
4622 -- the value of the _Master parameter, and _Chain as the value
4623 -- of the _Chain parameter (_Chain will be defined as part of
4624 -- the generated code for the allocator).
70482933 4625
b4592168
GD
4626 -- In Ada 2005, the context may be a function that returns an
4627 -- anonymous access type. In that case the Master_Id has been
4628 -- created when expanding the function declaration.
70482933 4629
b4592168
GD
4630 if Has_Task (T) then
4631 if No (Master_Id (Base_Type (PtrT))) then
70482933 4632
b4592168
GD
4633 -- The designated type was an incomplete type, and the
4634 -- access type did not get expanded. Salvage it now.
70482933 4635
b941ae65 4636 if not Restriction_Active (No_Task_Hierarchy) then
3d67b239
AC
4637 if Present (Parent (Base_Type (PtrT))) then
4638 Expand_N_Full_Type_Declaration
4639 (Parent (Base_Type (PtrT)));
4640
0d5fbf52
AC
4641 -- The only other possibility is an itype. For this
4642 -- case, the master must exist in the context. This is
4643 -- the case when the allocator initializes an access
4644 -- component in an init-proc.
3d67b239 4645
0d5fbf52 4646 else
3d67b239
AC
4647 pragma Assert (Is_Itype (PtrT));
4648 Build_Master_Renaming (PtrT, N);
4649 end if;
b941ae65 4650 end if;
b4592168 4651 end if;
70482933 4652
b4592168
GD
4653 -- If the context of the allocator is a declaration or an
4654 -- assignment, we can generate a meaningful image for it,
4655 -- even though subsequent assignments might remove the
4656 -- connection between task and entity. We build this image
4657 -- when the left-hand side is a simple variable, a simple
4658 -- indexed assignment or a simple selected component.
4659
4660 if Nkind (Parent (N)) = N_Assignment_Statement then
4661 declare
4662 Nam : constant Node_Id := Name (Parent (N));
4663
4664 begin
4665 if Is_Entity_Name (Nam) then
4666 Decls :=
4667 Build_Task_Image_Decls
4668 (Loc,
4669 New_Occurrence_Of
4670 (Entity (Nam), Sloc (Nam)), T);
4671
243cae0a
AC
4672 elsif Nkind_In (Nam, N_Indexed_Component,
4673 N_Selected_Component)
b4592168
GD
4674 and then Is_Entity_Name (Prefix (Nam))
4675 then
4676 Decls :=
4677 Build_Task_Image_Decls
4678 (Loc, Nam, Etype (Prefix (Nam)));
4679 else
4680 Decls := Build_Task_Image_Decls (Loc, T, T);
4681 end if;
4682 end;
70482933 4683
b4592168
GD
4684 elsif Nkind (Parent (N)) = N_Object_Declaration then
4685 Decls :=
4686 Build_Task_Image_Decls
4687 (Loc, Defining_Identifier (Parent (N)), T);
70482933 4688
b4592168
GD
4689 else
4690 Decls := Build_Task_Image_Decls (Loc, T, T);
4691 end if;
26bff3d9 4692
87dc09cb 4693 if Restriction_Active (No_Task_Hierarchy) then
3c1ecd7e
AC
4694 Append_To (Args,
4695 New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
87dc09cb
AC
4696 else
4697 Append_To (Args,
e4494292 4698 New_Occurrence_Of
87dc09cb
AC
4699 (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
4700 end if;
4701
b4592168 4702 Append_To (Args, Make_Identifier (Loc, Name_uChain));
26bff3d9 4703
b4592168
GD
4704 Decl := Last (Decls);
4705 Append_To (Args,
4706 New_Occurrence_Of (Defining_Identifier (Decl), Loc));
26bff3d9 4707
87dc09cb 4708 -- Has_Task is false, Decls not used
26bff3d9 4709
b4592168
GD
4710 else
4711 Decls := No_List;
26bff3d9
JM
4712 end if;
4713
b4592168
GD
4714 -- Add discriminants if discriminated type
4715
4716 declare
4717 Dis : Boolean := False;
4718 Typ : Entity_Id;
4719
4720 begin
4721 if Has_Discriminants (T) then
4722 Dis := True;
4723 Typ := T;
4724
4725 elsif Is_Private_Type (T)
4726 and then Present (Full_View (T))
4727 and then Has_Discriminants (Full_View (T))
20b5d666 4728 then
b4592168
GD
4729 Dis := True;
4730 Typ := Full_View (T);
20b5d666 4731 end if;
70482933 4732
b4592168 4733 if Dis then
26bff3d9 4734
b4592168 4735 -- If the allocated object will be constrained by the
685094bf
RD
4736 -- default values for discriminants, then build a subtype
4737 -- with those defaults, and change the allocated subtype
4738 -- to that. Note that this happens in fewer cases in Ada
4739 -- 2005 (AI-363).
26bff3d9 4740
b4592168
GD
4741 if not Is_Constrained (Typ)
4742 and then Present (Discriminant_Default_Value
df3e68b1 4743 (First_Discriminant (Typ)))
0791fbe9 4744 and then (Ada_Version < Ada_2005
cc96a1b8 4745 or else not
0fbcb11c
ES
4746 Object_Type_Has_Constrained_Partial_View
4747 (Typ, Current_Scope))
20b5d666 4748 then
b4592168 4749 Typ := Build_Default_Subtype (Typ, N);
e4494292 4750 Set_Expression (N, New_Occurrence_Of (Typ, Loc));
20b5d666
JM
4751 end if;
4752
b4592168
GD
4753 Discr := First_Elmt (Discriminant_Constraint (Typ));
4754 while Present (Discr) loop
4755 Nod := Node (Discr);
4756 Append (New_Copy_Tree (Node (Discr)), Args);
20b5d666 4757
b4592168
GD
4758 -- AI-416: when the discriminant constraint is an
4759 -- anonymous access type make sure an accessibility
4760 -- check is inserted if necessary (3.10.2(22.q/2))
20b5d666 4761
0791fbe9 4762 if Ada_Version >= Ada_2005
b4592168
GD
4763 and then
4764 Ekind (Etype (Nod)) = E_Anonymous_Access_Type
4765 then
e84e11ba
GD
4766 Apply_Accessibility_Check
4767 (Nod, Typ, Insert_Node => Nod);
b4592168 4768 end if;
20b5d666 4769
b4592168
GD
4770 Next_Elmt (Discr);
4771 end loop;
4772 end if;
4773 end;
70482933 4774
4b985e20 4775 -- We set the allocator as analyzed so that when we analyze
9b16cb57
RD
4776 -- the if expression node, we do not get an unwanted recursive
4777 -- expansion of the allocator expression.
70482933 4778
b4592168
GD
4779 Set_Analyzed (N, True);
4780 Nod := Relocate_Node (N);
70482933 4781
b4592168 4782 -- Here is the transformation:
ca5af305
AC
4783 -- input: new Ctrl_Typ
4784 -- output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
4785 -- Ctrl_TypIP (Temp.all, ...);
4786 -- [Deep_]Initialize (Temp.all);
70482933 4787
ca5af305
AC
4788 -- Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
4789 -- is the subtype of the allocator.
70482933 4790
b4592168
GD
4791 Temp_Decl :=
4792 Make_Object_Declaration (Loc,
4793 Defining_Identifier => Temp,
4794 Constant_Present => True,
e4494292 4795 Object_Definition => New_Occurrence_Of (Temp_Type, Loc),
b4592168 4796 Expression => Nod);
70482933 4797
b4592168
GD
4798 Set_Assignment_OK (Temp_Decl);
4799 Insert_Action (N, Temp_Decl, Suppress => All_Checks);
70482933 4800
ca5af305 4801 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 4802
b4592168
GD
4803 -- If the designated type is a task type or contains tasks,
4804 -- create block to activate created tasks, and insert
4805 -- declaration for Task_Image variable ahead of call.
70482933 4806
b4592168
GD
4807 if Has_Task (T) then
4808 declare
4809 L : constant List_Id := New_List;
4810 Blk : Node_Id;
4811 begin
4812 Build_Task_Allocate_Block (L, Nod, Args);
4813 Blk := Last (L);
4814 Insert_List_Before (First (Declarations (Blk)), Decls);
4815 Insert_Actions (N, L);
4816 end;
70482933 4817
b4592168
GD
4818 else
4819 Insert_Action (N,
4820 Make_Procedure_Call_Statement (Loc,
e4494292 4821 Name => New_Occurrence_Of (Init, Loc),
b4592168
GD
4822 Parameter_Associations => Args));
4823 end if;
70482933 4824
048e5cef 4825 if Needs_Finalization (T) then
70482933 4826
df3e68b1
HK
4827 -- Generate:
4828 -- [Deep_]Initialize (Init_Arg1);
70482933 4829
df3e68b1 4830 Insert_Action (N,
243cae0a
AC
4831 Make_Init_Call
4832 (Obj_Ref => New_Copy_Tree (Init_Arg1),
4833 Typ => T));
b4592168 4834
760804f3
AC
4835 -- Special processing for .NET/JVM, the allocated object is
4836 -- attached to the finalization master. Generate:
deb8dacc 4837
760804f3 4838 -- Attach (<PtrT>FM, Root_Controlled_Ptr (Init_Arg1));
b254da66 4839
760804f3
AC
4840 -- Types derived from [Limited_]Controlled are the only ones
4841 -- considered since they have fields Prev and Next.
b254da66 4842
760804f3
AC
4843 if VM_Target /= No_VM
4844 and then Is_Controlled (T)
4845 and then Present (Finalization_Master (PtrT))
4846 then
4847 Insert_Action (N,
4848 Make_Attach_Call
4849 (Obj_Ref => New_Copy_Tree (Init_Arg1),
4850 Ptr_Typ => PtrT));
b4592168 4851 end if;
70482933
RK
4852 end if;
4853
e4494292 4854 Rewrite (N, New_Occurrence_Of (Temp, Loc));
b4592168
GD
4855 Analyze_And_Resolve (N, PtrT);
4856 end if;
26bff3d9
JM
4857 end if;
4858 end;
f82944b7 4859
26bff3d9
JM
4860 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
4861 -- object that has been rewritten as a reference, we displace "this"
4862 -- to reference properly its secondary dispatch table.
4863
533369aa 4864 if Nkind (N) = N_Identifier and then Is_Interface (Dtyp) then
26bff3d9 4865 Displace_Allocator_Pointer (N);
f82944b7
JM
4866 end if;
4867
fbf5a39b
AC
4868 exception
4869 when RE_Not_Available =>
4870 return;
70482933
RK
4871 end Expand_N_Allocator;
4872
4873 -----------------------
4874 -- Expand_N_And_Then --
4875 -----------------------
4876
5875f8d6
AC
4877 procedure Expand_N_And_Then (N : Node_Id)
4878 renames Expand_Short_Circuit_Operator;
70482933 4879
19d846a0
RD
4880 ------------------------------
4881 -- Expand_N_Case_Expression --
4882 ------------------------------
4883
4884 procedure Expand_N_Case_Expression (N : Node_Id) is
4885 Loc : constant Source_Ptr := Sloc (N);
4886 Typ : constant Entity_Id := Etype (N);
4887 Cstmt : Node_Id;
27a8f150 4888 Decl : Node_Id;
19d846a0
RD
4889 Tnn : Entity_Id;
4890 Pnn : Entity_Id;
4891 Actions : List_Id;
4892 Ttyp : Entity_Id;
4893 Alt : Node_Id;
4894 Fexp : Node_Id;
4895
4896 begin
b6b5cca8
AC
4897 -- Check for MINIMIZED/ELIMINATED overflow mode
4898
4899 if Minimized_Eliminated_Overflow_Check (N) then
4b1c4f20
RD
4900 Apply_Arithmetic_Overflow_Check (N);
4901 return;
4902 end if;
4903
ff1f1705
AC
4904 -- If the case expression is a predicate specification, do not
4905 -- expand, because it will be converted to the proper predicate
4906 -- form when building the predicate function.
4907
4908 if Ekind_In (Current_Scope, E_Function, E_Procedure)
4909 and then Is_Predicate_Function (Current_Scope)
4910 then
4911 return;
4912 end if;
4913
19d846a0
RD
4914 -- We expand
4915
4916 -- case X is when A => AX, when B => BX ...
4917
4918 -- to
4919
4920 -- do
4921 -- Tnn : typ;
4922 -- case X is
4923 -- when A =>
4924 -- Tnn := AX;
4925 -- when B =>
4926 -- Tnn := BX;
4927 -- ...
4928 -- end case;
4929 -- in Tnn end;
4930
4931 -- However, this expansion is wrong for limited types, and also
4932 -- wrong for unconstrained types (since the bounds may not be the
4933 -- same in all branches). Furthermore it involves an extra copy
4934 -- for large objects. So we take care of this by using the following
2492305b 4935 -- modified expansion for non-elementary types:
19d846a0
RD
4936
4937 -- do
4938 -- type Pnn is access all typ;
4939 -- Tnn : Pnn;
4940 -- case X is
4941 -- when A =>
4942 -- T := AX'Unrestricted_Access;
4943 -- when B =>
4944 -- T := BX'Unrestricted_Access;
4945 -- ...
4946 -- end case;
4947 -- in Tnn.all end;
4948
4949 Cstmt :=
4950 Make_Case_Statement (Loc,
4951 Expression => Expression (N),
4952 Alternatives => New_List);
4953
414c6563
AC
4954 -- Preserve the original context for which the case statement is being
4955 -- generated. This is needed by the finalization machinery to prevent
4956 -- the premature finalization of controlled objects found within the
4957 -- case statement.
4958
4959 Set_From_Conditional_Expression (Cstmt);
4960
19d846a0
RD
4961 Actions := New_List;
4962
4963 -- Scalar case
4964
2492305b 4965 if Is_Elementary_Type (Typ) then
19d846a0
RD
4966 Ttyp := Typ;
4967
4968 else
4969 Pnn := Make_Temporary (Loc, 'P');
4970 Append_To (Actions,
4971 Make_Full_Type_Declaration (Loc,
4972 Defining_Identifier => Pnn,
11d59a86 4973 Type_Definition =>
19d846a0 4974 Make_Access_To_Object_Definition (Loc,
11d59a86 4975 All_Present => True,
e4494292 4976 Subtype_Indication => New_Occurrence_Of (Typ, Loc))));
19d846a0
RD
4977 Ttyp := Pnn;
4978 end if;
4979
4980 Tnn := Make_Temporary (Loc, 'T');
27a8f150
AC
4981
4982 -- Create declaration for target of expression, and indicate that it
4983 -- does not require initialization.
4984
11d59a86
AC
4985 Decl :=
4986 Make_Object_Declaration (Loc,
19d846a0 4987 Defining_Identifier => Tnn,
27a8f150
AC
4988 Object_Definition => New_Occurrence_Of (Ttyp, Loc));
4989 Set_No_Initialization (Decl);
4990 Append_To (Actions, Decl);
19d846a0
RD
4991
4992 -- Now process the alternatives
4993
4994 Alt := First (Alternatives (N));
4995 while Present (Alt) loop
4996 declare
eaed0c37
AC
4997 Aexp : Node_Id := Expression (Alt);
4998 Aloc : constant Source_Ptr := Sloc (Aexp);
4999 Stats : List_Id;
19d846a0
RD
5000
5001 begin
eaed0c37
AC
5002 -- As described above, take Unrestricted_Access for case of non-
5003 -- scalar types, to avoid big copies, and special cases.
05dbd302 5004
2492305b 5005 if not Is_Elementary_Type (Typ) then
19d846a0
RD
5006 Aexp :=
5007 Make_Attribute_Reference (Aloc,
5008 Prefix => Relocate_Node (Aexp),
5009 Attribute_Name => Name_Unrestricted_Access);
5010 end if;
5011
eaed0c37
AC
5012 Stats := New_List (
5013 Make_Assignment_Statement (Aloc,
5014 Name => New_Occurrence_Of (Tnn, Loc),
5015 Expression => Aexp));
5016
5017 -- Propagate declarations inserted in the node by Insert_Actions
5018 -- (for example, temporaries generated to remove side effects).
5019 -- These actions must remain attached to the alternative, given
5020 -- that they are generated by the corresponding expression.
5021
5022 if Present (Sinfo.Actions (Alt)) then
5023 Prepend_List (Sinfo.Actions (Alt), Stats);
5024 end if;
5025
19d846a0
RD
5026 Append_To
5027 (Alternatives (Cstmt),
5028 Make_Case_Statement_Alternative (Sloc (Alt),
5029 Discrete_Choices => Discrete_Choices (Alt),
eaed0c37 5030 Statements => Stats));
19d846a0
RD
5031 end;
5032
5033 Next (Alt);
5034 end loop;
5035
5036 Append_To (Actions, Cstmt);
5037
5038 -- Construct and return final expression with actions
5039
2492305b 5040 if Is_Elementary_Type (Typ) then
19d846a0
RD
5041 Fexp := New_Occurrence_Of (Tnn, Loc);
5042 else
5043 Fexp :=
5044 Make_Explicit_Dereference (Loc,
5045 Prefix => New_Occurrence_Of (Tnn, Loc));
5046 end if;
5047
5048 Rewrite (N,
5049 Make_Expression_With_Actions (Loc,
5050 Expression => Fexp,
5051 Actions => Actions));
5052
5053 Analyze_And_Resolve (N, Typ);
5054 end Expand_N_Case_Expression;
5055
9b16cb57
RD
5056 -----------------------------------
5057 -- Expand_N_Explicit_Dereference --
5058 -----------------------------------
5059
5060 procedure Expand_N_Explicit_Dereference (N : Node_Id) is
5061 begin
5062 -- Insert explicit dereference call for the checked storage pool case
5063
5064 Insert_Dereference_Action (Prefix (N));
5065
5066 -- If the type is an Atomic type for which Atomic_Sync is enabled, then
5067 -- we set the atomic sync flag.
5068
5069 if Is_Atomic (Etype (N))
5070 and then not Atomic_Synchronization_Disabled (Etype (N))
5071 then
5072 Activate_Atomic_Synchronization (N);
5073 end if;
5074 end Expand_N_Explicit_Dereference;
5075
5076 --------------------------------------
5077 -- Expand_N_Expression_With_Actions --
5078 --------------------------------------
5079
5080 procedure Expand_N_Expression_With_Actions (N : Node_Id) is
4c7e0990 5081 function Process_Action (Act : Node_Id) return Traverse_Result;
b2c28399
AC
5082 -- Inspect and process a single action of an expression_with_actions for
5083 -- transient controlled objects. If such objects are found, the routine
5084 -- generates code to clean them up when the context of the expression is
5085 -- evaluated or elaborated.
9b16cb57 5086
4c7e0990
AC
5087 --------------------
5088 -- Process_Action --
5089 --------------------
5090
5091 function Process_Action (Act : Node_Id) return Traverse_Result is
4c7e0990
AC
5092 begin
5093 if Nkind (Act) = N_Object_Declaration
5094 and then Is_Finalizable_Transient (Act, N)
5095 then
b2c28399
AC
5096 Process_Transient_Object (Act, N);
5097 return Abandon;
9b16cb57 5098
4c7e0990
AC
5099 -- Avoid processing temporary function results multiple times when
5100 -- dealing with nested expression_with_actions.
9b16cb57 5101
4c7e0990
AC
5102 elsif Nkind (Act) = N_Expression_With_Actions then
5103 return Abandon;
5104
b2c28399
AC
5105 -- Do not process temporary function results in loops. This is done
5106 -- by Expand_N_Loop_Statement and Build_Finalizer.
4c7e0990
AC
5107
5108 elsif Nkind (Act) = N_Loop_Statement then
5109 return Abandon;
9b16cb57
RD
5110 end if;
5111
4c7e0990
AC
5112 return OK;
5113 end Process_Action;
9b16cb57 5114
4c7e0990 5115 procedure Process_Single_Action is new Traverse_Proc (Process_Action);
9b16cb57
RD
5116
5117 -- Local variables
5118
4b17187f
AC
5119 Acts : constant List_Id := Actions (N);
5120 Expr : constant Node_Id := Expression (N);
5121 Act : Node_Id;
9b16cb57
RD
5122
5123 -- Start of processing for Expand_N_Expression_With_Actions
5124
5125 begin
4b17187f
AC
5126 -- Do not evaluate the expression when it denotes an entity because the
5127 -- expression_with_actions node will be replaced by the reference.
5128
5129 if Is_Entity_Name (Expr) then
5130 null;
5131
5132 -- Do not evaluate the expression when there are no actions because the
5133 -- expression_with_actions node will be replaced by the expression.
5134
5135 elsif No (Acts) or else Is_Empty_List (Acts) then
5136 null;
5137
5138 -- Force the evaluation of the expression by capturing its value in a
5139 -- temporary. This ensures that aliases of transient controlled objects
5140 -- do not leak to the expression of the expression_with_actions node:
5141
5142 -- do
5143 -- Trans_Id : Ctrl_Typ : ...;
5144 -- Alias : ... := Trans_Id;
5145 -- in ... Alias ... end;
5146
5147 -- In the example above, Trans_Id cannot be finalized at the end of the
5148 -- actions list because this may affect the alias and the final value of
5149 -- the expression_with_actions. Forcing the evaluation encapsulates the
5150 -- reference to the Alias within the actions list:
5151
5152 -- do
5153 -- Trans_Id : Ctrl_Typ : ...;
5154 -- Alias : ... := Trans_Id;
5155 -- Val : constant Boolean := ... Alias ...;
5156 -- <finalize Trans_Id>
5157 -- in Val end;
e0f63680 5158
4b17187f
AC
5159 -- It is now safe to finalize the transient controlled object at the end
5160 -- of the actions list.
5161
5162 else
5163 Force_Evaluation (Expr);
5164 end if;
5165
5166 -- Process all transient controlled objects found within the actions of
5167 -- the EWA node.
5168
5169 Act := First (Acts);
e0f63680
AC
5170 while Present (Act) loop
5171 Process_Single_Action (Act);
5172 Next (Act);
5173 end loop;
5174
ebdaa81b 5175 -- Deal with case where there are no actions. In this case we simply
5a521b8a 5176 -- rewrite the node with its expression since we don't need the actions
ebdaa81b
AC
5177 -- and the specification of this node does not allow a null action list.
5178
5a521b8a
AC
5179 -- Note: we use Rewrite instead of Replace, because Codepeer is using
5180 -- the expanded tree and relying on being able to retrieve the original
5181 -- tree in cases like this. This raises a whole lot of issues of whether
5182 -- we have problems elsewhere, which will be addressed in the future???
5183
4b17187f 5184 if Is_Empty_List (Acts) then
5a521b8a 5185 Rewrite (N, Relocate_Node (Expression (N)));
ebdaa81b 5186 end if;
9b16cb57
RD
5187 end Expand_N_Expression_With_Actions;
5188
5189 ----------------------------
5190 -- Expand_N_If_Expression --
5191 ----------------------------
70482933 5192
4b985e20 5193 -- Deal with limited types and condition actions
70482933 5194
9b16cb57 5195 procedure Expand_N_If_Expression (N : Node_Id) is
b2c28399
AC
5196 procedure Process_Actions (Actions : List_Id);
5197 -- Inspect and process a single action list of an if expression for
5198 -- transient controlled objects. If such objects are found, the routine
5199 -- generates code to clean them up when the context of the expression is
5200 -- evaluated or elaborated.
3cebd1c0 5201
b2c28399
AC
5202 ---------------------
5203 -- Process_Actions --
5204 ---------------------
3cebd1c0 5205
b2c28399
AC
5206 procedure Process_Actions (Actions : List_Id) is
5207 Act : Node_Id;
3cebd1c0
AC
5208
5209 begin
b2c28399
AC
5210 Act := First (Actions);
5211 while Present (Act) loop
5212 if Nkind (Act) = N_Object_Declaration
5213 and then Is_Finalizable_Transient (Act, N)
5214 then
5215 Process_Transient_Object (Act, N);
5216 end if;
3cebd1c0 5217
b2c28399
AC
5218 Next (Act);
5219 end loop;
5220 end Process_Actions;
3cebd1c0
AC
5221
5222 -- Local variables
5223
70482933
RK
5224 Loc : constant Source_Ptr := Sloc (N);
5225 Cond : constant Node_Id := First (Expressions (N));
5226 Thenx : constant Node_Id := Next (Cond);
5227 Elsex : constant Node_Id := Next (Thenx);
5228 Typ : constant Entity_Id := Etype (N);
c471e2da 5229
3cebd1c0 5230 Actions : List_Id;
602a7ec0
AC
5231 Cnn : Entity_Id;
5232 Decl : Node_Id;
3cebd1c0 5233 Expr : Node_Id;
602a7ec0
AC
5234 New_If : Node_Id;
5235 New_N : Node_Id;
b2c28399 5236 Ptr_Typ : Entity_Id;
70482933 5237
a53c5613
AC
5238 -- Start of processing for Expand_N_If_Expression
5239
70482933 5240 begin
b6b5cca8
AC
5241 -- Check for MINIMIZED/ELIMINATED overflow mode
5242
5243 if Minimized_Eliminated_Overflow_Check (N) then
5244 Apply_Arithmetic_Overflow_Check (N);
5245 return;
5246 end if;
5247
602a7ec0 5248 -- Fold at compile time if condition known. We have already folded
9b16cb57
RD
5249 -- static if expressions, but it is possible to fold any case in which
5250 -- the condition is known at compile time, even though the result is
5251 -- non-static.
602a7ec0
AC
5252
5253 -- Note that we don't do the fold of such cases in Sem_Elab because
5254 -- it can cause infinite loops with the expander adding a conditional
5255 -- expression, and Sem_Elab circuitry removing it repeatedly.
5256
5257 if Compile_Time_Known_Value (Cond) then
5258 if Is_True (Expr_Value (Cond)) then
cc6f5d75 5259 Expr := Thenx;
602a7ec0
AC
5260 Actions := Then_Actions (N);
5261 else
cc6f5d75 5262 Expr := Elsex;
602a7ec0
AC
5263 Actions := Else_Actions (N);
5264 end if;
5265
5266 Remove (Expr);
ae77c68b
AC
5267
5268 if Present (Actions) then
ae77c68b
AC
5269 Rewrite (N,
5270 Make_Expression_With_Actions (Loc,
5271 Expression => Relocate_Node (Expr),
5272 Actions => Actions));
5273 Analyze_And_Resolve (N, Typ);
ae77c68b
AC
5274 else
5275 Rewrite (N, Relocate_Node (Expr));
5276 end if;
602a7ec0
AC
5277
5278 -- Note that the result is never static (legitimate cases of static
9b16cb57 5279 -- if expressions were folded in Sem_Eval).
602a7ec0
AC
5280
5281 Set_Is_Static_Expression (N, False);
5282 return;
5283 end if;
5284
113a9fb6
AC
5285 -- If the type is limited, and the back end does not handle limited
5286 -- types, then we expand as follows to avoid the possibility of
5287 -- improper copying.
ac7120ce 5288
c471e2da
AC
5289 -- type Ptr is access all Typ;
5290 -- Cnn : Ptr;
ac7120ce
RD
5291 -- if cond then
5292 -- <<then actions>>
5293 -- Cnn := then-expr'Unrestricted_Access;
5294 -- else
5295 -- <<else actions>>
5296 -- Cnn := else-expr'Unrestricted_Access;
5297 -- end if;
5298
9b16cb57 5299 -- and replace the if expression by a reference to Cnn.all.
ac7120ce 5300
305caf42
AC
5301 -- This special case can be skipped if the back end handles limited
5302 -- types properly and ensures that no incorrect copies are made.
5303
5304 if Is_By_Reference_Type (Typ)
5305 and then not Back_End_Handles_Limited_Types
5306 then
b2c28399
AC
5307 -- When the "then" or "else" expressions involve controlled function
5308 -- calls, generated temporaries are chained on the corresponding list
5309 -- of actions. These temporaries need to be finalized after the if
5310 -- expression is evaluated.
3cebd1c0 5311
b2c28399
AC
5312 Process_Actions (Then_Actions (N));
5313 Process_Actions (Else_Actions (N));
3cebd1c0 5314
b2c28399
AC
5315 -- Generate:
5316 -- type Ann is access all Typ;
3cebd1c0 5317
b2c28399 5318 Ptr_Typ := Make_Temporary (Loc, 'A');
3cebd1c0 5319
b2c28399
AC
5320 Insert_Action (N,
5321 Make_Full_Type_Declaration (Loc,
5322 Defining_Identifier => Ptr_Typ,
5323 Type_Definition =>
5324 Make_Access_To_Object_Definition (Loc,
5325 All_Present => True,
e4494292 5326 Subtype_Indication => New_Occurrence_Of (Typ, Loc))));
3cebd1c0 5327
b2c28399
AC
5328 -- Generate:
5329 -- Cnn : Ann;
3cebd1c0 5330
b2c28399 5331 Cnn := Make_Temporary (Loc, 'C', N);
3cebd1c0 5332
b2c28399
AC
5333 Decl :=
5334 Make_Object_Declaration (Loc,
5335 Defining_Identifier => Cnn,
5336 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc));
3cebd1c0 5337
b2c28399
AC
5338 -- Generate:
5339 -- if Cond then
5340 -- Cnn := <Thenx>'Unrestricted_Access;
5341 -- else
5342 -- Cnn := <Elsex>'Unrestricted_Access;
5343 -- end if;
3cebd1c0 5344
b2c28399
AC
5345 New_If :=
5346 Make_Implicit_If_Statement (N,
5347 Condition => Relocate_Node (Cond),
5348 Then_Statements => New_List (
5349 Make_Assignment_Statement (Sloc (Thenx),
e4494292 5350 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
b2c28399
AC
5351 Expression =>
5352 Make_Attribute_Reference (Loc,
5353 Prefix => Relocate_Node (Thenx),
5354 Attribute_Name => Name_Unrestricted_Access))),
3cebd1c0 5355
b2c28399
AC
5356 Else_Statements => New_List (
5357 Make_Assignment_Statement (Sloc (Elsex),
e4494292 5358 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
b2c28399
AC
5359 Expression =>
5360 Make_Attribute_Reference (Loc,
5361 Prefix => Relocate_Node (Elsex),
5362 Attribute_Name => Name_Unrestricted_Access))));
3cebd1c0 5363
414c6563
AC
5364 -- Preserve the original context for which the if statement is being
5365 -- generated. This is needed by the finalization machinery to prevent
5366 -- the premature finalization of controlled objects found within the
5367 -- if statement.
5368
5369 Set_From_Conditional_Expression (New_If);
5370
5371 New_N :=
5372 Make_Explicit_Dereference (Loc,
5373 Prefix => New_Occurrence_Of (Cnn, Loc));
fb1949a0 5374
113a9fb6
AC
5375 -- If the result is an unconstrained array and the if expression is in a
5376 -- context other than the initializing expression of the declaration of
5377 -- an object, then we pull out the if expression as follows:
5378
5379 -- Cnn : constant typ := if-expression
5380
5381 -- and then replace the if expression with an occurrence of Cnn. This
5382 -- avoids the need in the back end to create on-the-fly variable length
5383 -- temporaries (which it cannot do!)
5384
5385 -- Note that the test for being in an object declaration avoids doing an
5386 -- unnecessary expansion, and also avoids infinite recursion.
5387
5388 elsif Is_Array_Type (Typ) and then not Is_Constrained (Typ)
5389 and then (Nkind (Parent (N)) /= N_Object_Declaration
5390 or else Expression (Parent (N)) /= N)
5391 then
5392 declare
5393 Cnn : constant Node_Id := Make_Temporary (Loc, 'C', N);
5394 begin
5395 Insert_Action (N,
5396 Make_Object_Declaration (Loc,
5397 Defining_Identifier => Cnn,
5398 Constant_Present => True,
5399 Object_Definition => New_Occurrence_Of (Typ, Loc),
5400 Expression => Relocate_Node (N),
5401 Has_Init_Expression => True));
5402
5403 Rewrite (N, New_Occurrence_Of (Cnn, Loc));
5404 return;
5405 end;
5406
c471e2da
AC
5407 -- For other types, we only need to expand if there are other actions
5408 -- associated with either branch.
5409
5410 elsif Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
c471e2da 5411
0812b84e 5412 -- We now wrap the actions into the appropriate expression
fb1949a0 5413
0812b84e
AC
5414 if Present (Then_Actions (N)) then
5415 Rewrite (Thenx,
b2c28399
AC
5416 Make_Expression_With_Actions (Sloc (Thenx),
5417 Actions => Then_Actions (N),
5418 Expression => Relocate_Node (Thenx)));
5419
0812b84e
AC
5420 Set_Then_Actions (N, No_List);
5421 Analyze_And_Resolve (Thenx, Typ);
5422 end if;
305caf42 5423
0812b84e
AC
5424 if Present (Else_Actions (N)) then
5425 Rewrite (Elsex,
b2c28399
AC
5426 Make_Expression_With_Actions (Sloc (Elsex),
5427 Actions => Else_Actions (N),
5428 Expression => Relocate_Node (Elsex)));
5429
0812b84e
AC
5430 Set_Else_Actions (N, No_List);
5431 Analyze_And_Resolve (Elsex, Typ);
305caf42
AC
5432 end if;
5433
0812b84e
AC
5434 return;
5435
b2c28399
AC
5436 -- If no actions then no expansion needed, gigi will handle it using the
5437 -- same approach as a C conditional expression.
305caf42
AC
5438
5439 else
c471e2da
AC
5440 return;
5441 end if;
5442
305caf42
AC
5443 -- Fall through here for either the limited expansion, or the case of
5444 -- inserting actions for non-limited types. In both these cases, we must
5445 -- move the SLOC of the parent If statement to the newly created one and
3fc5d116
RD
5446 -- change it to the SLOC of the expression which, after expansion, will
5447 -- correspond to what is being evaluated.
c471e2da 5448
533369aa 5449 if Present (Parent (N)) and then Nkind (Parent (N)) = N_If_Statement then
c471e2da
AC
5450 Set_Sloc (New_If, Sloc (Parent (N)));
5451 Set_Sloc (Parent (N), Loc);
5452 end if;
70482933 5453
3fc5d116
RD
5454 -- Make sure Then_Actions and Else_Actions are appropriately moved
5455 -- to the new if statement.
5456
c471e2da
AC
5457 if Present (Then_Actions (N)) then
5458 Insert_List_Before
5459 (First (Then_Statements (New_If)), Then_Actions (N));
70482933 5460 end if;
c471e2da
AC
5461
5462 if Present (Else_Actions (N)) then
5463 Insert_List_Before
5464 (First (Else_Statements (New_If)), Else_Actions (N));
5465 end if;
5466
5467 Insert_Action (N, Decl);
5468 Insert_Action (N, New_If);
5469 Rewrite (N, New_N);
5470 Analyze_And_Resolve (N, Typ);
9b16cb57 5471 end Expand_N_If_Expression;
35a1c212 5472
70482933
RK
5473 -----------------
5474 -- Expand_N_In --
5475 -----------------
5476
5477 procedure Expand_N_In (N : Node_Id) is
7324bf49 5478 Loc : constant Source_Ptr := Sloc (N);
4818e7b9 5479 Restyp : constant Entity_Id := Etype (N);
7324bf49
AC
5480 Lop : constant Node_Id := Left_Opnd (N);
5481 Rop : constant Node_Id := Right_Opnd (N);
5482 Static : constant Boolean := Is_OK_Static_Expression (N);
70482933 5483
4818e7b9
RD
5484 Ltyp : Entity_Id;
5485 Rtyp : Entity_Id;
5486
630d30e9
RD
5487 procedure Substitute_Valid_Check;
5488 -- Replaces node N by Lop'Valid. This is done when we have an explicit
5489 -- test for the left operand being in range of its subtype.
5490
5491 ----------------------------
5492 -- Substitute_Valid_Check --
5493 ----------------------------
5494
5495 procedure Substitute_Valid_Check is
5496 begin
c7532b2d
AC
5497 Rewrite (N,
5498 Make_Attribute_Reference (Loc,
5499 Prefix => Relocate_Node (Lop),
5500 Attribute_Name => Name_Valid));
630d30e9 5501
c7532b2d 5502 Analyze_And_Resolve (N, Restyp);
630d30e9 5503
acad3c0a
AC
5504 -- Give warning unless overflow checking is MINIMIZED or ELIMINATED,
5505 -- in which case, this usage makes sense, and in any case, we have
5506 -- actually eliminated the danger of optimization above.
5507
a7f1b24f 5508 if Overflow_Check_Mode not in Minimized_Or_Eliminated then
324ac540
AC
5509 Error_Msg_N
5510 ("??explicit membership test may be optimized away", N);
acad3c0a 5511 Error_Msg_N -- CODEFIX
324ac540 5512 ("\??use ''Valid attribute instead", N);
acad3c0a
AC
5513 end if;
5514
c7532b2d 5515 return;
630d30e9
RD
5516 end Substitute_Valid_Check;
5517
5518 -- Start of processing for Expand_N_In
5519
70482933 5520 begin
308e6f3a 5521 -- If set membership case, expand with separate procedure
4818e7b9 5522
197e4514 5523 if Present (Alternatives (N)) then
a3068ca6 5524 Expand_Set_Membership (N);
197e4514
AC
5525 return;
5526 end if;
5527
4818e7b9
RD
5528 -- Not set membership, proceed with expansion
5529
5530 Ltyp := Etype (Left_Opnd (N));
5531 Rtyp := Etype (Right_Opnd (N));
5532
5707e389 5533 -- If MINIMIZED/ELIMINATED overflow mode and type is a signed integer
f6194278
RD
5534 -- type, then expand with a separate procedure. Note the use of the
5535 -- flag No_Minimize_Eliminate to prevent infinite recursion.
5536
a7f1b24f 5537 if Overflow_Check_Mode in Minimized_Or_Eliminated
f6194278
RD
5538 and then Is_Signed_Integer_Type (Ltyp)
5539 and then not No_Minimize_Eliminate (N)
5540 then
5541 Expand_Membership_Minimize_Eliminate_Overflow (N);
5542 return;
5543 end if;
5544
630d30e9
RD
5545 -- Check case of explicit test for an expression in range of its
5546 -- subtype. This is suspicious usage and we replace it with a 'Valid
b6b5cca8 5547 -- test and give a warning for scalar types.
630d30e9 5548
4818e7b9 5549 if Is_Scalar_Type (Ltyp)
b6b5cca8
AC
5550
5551 -- Only relevant for source comparisons
5552
5553 and then Comes_From_Source (N)
5554
5555 -- In floating-point this is a standard way to check for finite values
5556 -- and using 'Valid would typically be a pessimization.
5557
4818e7b9 5558 and then not Is_Floating_Point_Type (Ltyp)
b6b5cca8
AC
5559
5560 -- Don't give the message unless right operand is a type entity and
5561 -- the type of the left operand matches this type. Note that this
5562 -- eliminates the cases where MINIMIZED/ELIMINATED mode overflow
5563 -- checks have changed the type of the left operand.
5564
630d30e9 5565 and then Nkind (Rop) in N_Has_Entity
4818e7b9 5566 and then Ltyp = Entity (Rop)
b6b5cca8
AC
5567
5568 -- Skip in VM mode, where we have no sense of invalid values. The
5569 -- warning still seems relevant, but not important enough to worry.
5570
26bff3d9 5571 and then VM_Target = No_VM
b6b5cca8
AC
5572
5573 -- Skip this for predicated types, where such expressions are a
5574 -- reasonable way of testing if something meets the predicate.
5575
3d6db7f8 5576 and then not Present (Predicate_Function (Ltyp))
630d30e9
RD
5577 then
5578 Substitute_Valid_Check;
5579 return;
5580 end if;
5581
20b5d666
JM
5582 -- Do validity check on operands
5583
5584 if Validity_Checks_On and Validity_Check_Operands then
5585 Ensure_Valid (Left_Opnd (N));
5586 Validity_Check_Range (Right_Opnd (N));
5587 end if;
5588
630d30e9 5589 -- Case of explicit range
fbf5a39b
AC
5590
5591 if Nkind (Rop) = N_Range then
5592 declare
630d30e9
RD
5593 Lo : constant Node_Id := Low_Bound (Rop);
5594 Hi : constant Node_Id := High_Bound (Rop);
5595
5596 Lo_Orig : constant Node_Id := Original_Node (Lo);
5597 Hi_Orig : constant Node_Id := Original_Node (Hi);
5598
c800f862
RD
5599 Lcheck : Compare_Result;
5600 Ucheck : Compare_Result;
fbf5a39b 5601
d766cee3
RD
5602 Warn1 : constant Boolean :=
5603 Constant_Condition_Warnings
c800f862
RD
5604 and then Comes_From_Source (N)
5605 and then not In_Instance;
d766cee3 5606 -- This must be true for any of the optimization warnings, we
9a0ddeee
AC
5607 -- clearly want to give them only for source with the flag on. We
5608 -- also skip these warnings in an instance since it may be the
5609 -- case that different instantiations have different ranges.
d766cee3
RD
5610
5611 Warn2 : constant Boolean :=
5612 Warn1
5613 and then Nkind (Original_Node (Rop)) = N_Range
5614 and then Is_Integer_Type (Etype (Lo));
5615 -- For the case where only one bound warning is elided, we also
5616 -- insist on an explicit range and an integer type. The reason is
5617 -- that the use of enumeration ranges including an end point is
9a0ddeee
AC
5618 -- common, as is the use of a subtype name, one of whose bounds is
5619 -- the same as the type of the expression.
d766cee3 5620
fbf5a39b 5621 begin
c95e0edc 5622 -- If test is explicit x'First .. x'Last, replace by valid check
630d30e9 5623
e606088a
AC
5624 -- Could use some individual comments for this complex test ???
5625
d766cee3 5626 if Is_Scalar_Type (Ltyp)
b6b5cca8
AC
5627
5628 -- And left operand is X'First where X matches left operand
5629 -- type (this eliminates cases of type mismatch, including
5630 -- the cases where ELIMINATED/MINIMIZED mode has changed the
5631 -- type of the left operand.
5632
630d30e9
RD
5633 and then Nkind (Lo_Orig) = N_Attribute_Reference
5634 and then Attribute_Name (Lo_Orig) = Name_First
5635 and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
d766cee3 5636 and then Entity (Prefix (Lo_Orig)) = Ltyp
b6b5cca8 5637
cc6f5d75 5638 -- Same tests for right operand
b6b5cca8 5639
630d30e9
RD
5640 and then Nkind (Hi_Orig) = N_Attribute_Reference
5641 and then Attribute_Name (Hi_Orig) = Name_Last
5642 and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
d766cee3 5643 and then Entity (Prefix (Hi_Orig)) = Ltyp
b6b5cca8
AC
5644
5645 -- Relevant only for source cases
5646
630d30e9 5647 and then Comes_From_Source (N)
b6b5cca8
AC
5648
5649 -- Omit for VM cases, where we don't have invalid values
5650
26bff3d9 5651 and then VM_Target = No_VM
630d30e9
RD
5652 then
5653 Substitute_Valid_Check;
4818e7b9 5654 goto Leave;
630d30e9
RD
5655 end if;
5656
d766cee3
RD
5657 -- If bounds of type are known at compile time, and the end points
5658 -- are known at compile time and identical, this is another case
5659 -- for substituting a valid test. We only do this for discrete
5660 -- types, since it won't arise in practice for float types.
5661
5662 if Comes_From_Source (N)
5663 and then Is_Discrete_Type (Ltyp)
5664 and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
5665 and then Compile_Time_Known_Value (Type_Low_Bound (Ltyp))
5666 and then Compile_Time_Known_Value (Lo)
5667 and then Compile_Time_Known_Value (Hi)
5668 and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
5669 and then Expr_Value (Type_Low_Bound (Ltyp)) = Expr_Value (Lo)
94eefd2e 5670
f6194278
RD
5671 -- Kill warnings in instances, since they may be cases where we
5672 -- have a test in the generic that makes sense with some types
5673 -- and not with other types.
94eefd2e
RD
5674
5675 and then not In_Instance
d766cee3
RD
5676 then
5677 Substitute_Valid_Check;
4818e7b9 5678 goto Leave;
d766cee3
RD
5679 end if;
5680
9a0ddeee
AC
5681 -- If we have an explicit range, do a bit of optimization based on
5682 -- range analysis (we may be able to kill one or both checks).
630d30e9 5683
c800f862
RD
5684 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
5685 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);
5686
630d30e9
RD
5687 -- If either check is known to fail, replace result by False since
5688 -- the other check does not matter. Preserve the static flag for
5689 -- legality checks, because we are constant-folding beyond RM 4.9.
fbf5a39b
AC
5690
5691 if Lcheck = LT or else Ucheck = GT then
c800f862 5692 if Warn1 then
685bc70f
AC
5693 Error_Msg_N ("?c?range test optimized away", N);
5694 Error_Msg_N ("\?c?value is known to be out of range", N);
d766cee3
RD
5695 end if;
5696
e4494292 5697 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
4818e7b9 5698 Analyze_And_Resolve (N, Restyp);
7324bf49 5699 Set_Is_Static_Expression (N, Static);
4818e7b9 5700 goto Leave;
fbf5a39b 5701
685094bf
RD
5702 -- If both checks are known to succeed, replace result by True,
5703 -- since we know we are in range.
fbf5a39b
AC
5704
5705 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
c800f862 5706 if Warn1 then
685bc70f
AC
5707 Error_Msg_N ("?c?range test optimized away", N);
5708 Error_Msg_N ("\?c?value is known to be in range", N);
d766cee3
RD
5709 end if;
5710
e4494292 5711 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
4818e7b9 5712 Analyze_And_Resolve (N, Restyp);
7324bf49 5713 Set_Is_Static_Expression (N, Static);
4818e7b9 5714 goto Leave;
fbf5a39b 5715
d766cee3
RD
5716 -- If lower bound check succeeds and upper bound check is not
5717 -- known to succeed or fail, then replace the range check with
5718 -- a comparison against the upper bound.
fbf5a39b
AC
5719
5720 elsif Lcheck in Compare_GE then
94eefd2e 5721 if Warn2 and then not In_Instance then
324ac540
AC
5722 Error_Msg_N ("??lower bound test optimized away", Lo);
5723 Error_Msg_N ("\??value is known to be in range", Lo);
d766cee3
RD
5724 end if;
5725
fbf5a39b
AC
5726 Rewrite (N,
5727 Make_Op_Le (Loc,
5728 Left_Opnd => Lop,
5729 Right_Opnd => High_Bound (Rop)));
4818e7b9
RD
5730 Analyze_And_Resolve (N, Restyp);
5731 goto Leave;
fbf5a39b 5732
d766cee3
RD
5733 -- If upper bound check succeeds and lower bound check is not
5734 -- known to succeed or fail, then replace the range check with
5735 -- a comparison against the lower bound.
fbf5a39b
AC
5736
5737 elsif Ucheck in Compare_LE then
94eefd2e 5738 if Warn2 and then not In_Instance then
324ac540
AC
5739 Error_Msg_N ("??upper bound test optimized away", Hi);
5740 Error_Msg_N ("\??value is known to be in range", Hi);
d766cee3
RD
5741 end if;
5742
fbf5a39b
AC
5743 Rewrite (N,
5744 Make_Op_Ge (Loc,
5745 Left_Opnd => Lop,
5746 Right_Opnd => Low_Bound (Rop)));
4818e7b9
RD
5747 Analyze_And_Resolve (N, Restyp);
5748 goto Leave;
fbf5a39b 5749 end if;
c800f862
RD
5750
5751 -- We couldn't optimize away the range check, but there is one
5752 -- more issue. If we are checking constant conditionals, then we
5753 -- see if we can determine the outcome assuming everything is
5754 -- valid, and if so give an appropriate warning.
5755
5756 if Warn1 and then not Assume_No_Invalid_Values then
5757 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
5758 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
5759
5760 -- Result is out of range for valid value
5761
5762 if Lcheck = LT or else Ucheck = GT then
ed2233dc 5763 Error_Msg_N
685bc70f 5764 ("?c?value can only be in range if it is invalid", N);
c800f862
RD
5765
5766 -- Result is in range for valid value
5767
5768 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
ed2233dc 5769 Error_Msg_N
685bc70f 5770 ("?c?value can only be out of range if it is invalid", N);
c800f862
RD
5771
5772 -- Lower bound check succeeds if value is valid
5773
5774 elsif Warn2 and then Lcheck in Compare_GE then
ed2233dc 5775 Error_Msg_N
685bc70f 5776 ("?c?lower bound check only fails if it is invalid", Lo);
c800f862
RD
5777
5778 -- Upper bound check succeeds if value is valid
5779
5780 elsif Warn2 and then Ucheck in Compare_LE then
ed2233dc 5781 Error_Msg_N
685bc70f 5782 ("?c?upper bound check only fails for invalid values", Hi);
c800f862
RD
5783 end if;
5784 end if;
fbf5a39b
AC
5785 end;
5786
5787 -- For all other cases of an explicit range, nothing to be done
70482933 5788
4818e7b9 5789 goto Leave;
70482933
RK
5790
5791 -- Here right operand is a subtype mark
5792
5793 else
5794 declare
82878151
AC
5795 Typ : Entity_Id := Etype (Rop);
5796 Is_Acc : constant Boolean := Is_Access_Type (Typ);
5797 Cond : Node_Id := Empty;
5798 New_N : Node_Id;
5799 Obj : Node_Id := Lop;
5800 SCIL_Node : Node_Id;
70482933
RK
5801
5802 begin
5803 Remove_Side_Effects (Obj);
5804
5805 -- For tagged type, do tagged membership operation
5806
5807 if Is_Tagged_Type (Typ) then
fbf5a39b 5808
26bff3d9
JM
5809 -- No expansion will be performed when VM_Target, as the VM
5810 -- back-ends will handle the membership tests directly (tags
5811 -- are not explicitly represented in Java objects, so the
5812 -- normal tagged membership expansion is not what we want).
70482933 5813
1f110335 5814 if Tagged_Type_Expansion then
82878151
AC
5815 Tagged_Membership (N, SCIL_Node, New_N);
5816 Rewrite (N, New_N);
4818e7b9 5817 Analyze_And_Resolve (N, Restyp);
82878151
AC
5818
5819 -- Update decoration of relocated node referenced by the
5820 -- SCIL node.
5821
9a0ddeee 5822 if Generate_SCIL and then Present (SCIL_Node) then
7665e4bd 5823 Set_SCIL_Node (N, SCIL_Node);
82878151 5824 end if;
70482933
RK
5825 end if;
5826
4818e7b9 5827 goto Leave;
70482933 5828
c95e0edc 5829 -- If type is scalar type, rewrite as x in t'First .. t'Last.
70482933 5830 -- This reason we do this is that the bounds may have the wrong
c800f862
RD
5831 -- type if they come from the original type definition. Also this
5832 -- way we get all the processing above for an explicit range.
70482933 5833
f6194278 5834 -- Don't do this for predicated types, since in this case we
a90bd866 5835 -- want to check the predicate.
c0f136cd 5836
c7532b2d
AC
5837 elsif Is_Scalar_Type (Typ) then
5838 if No (Predicate_Function (Typ)) then
5839 Rewrite (Rop,
5840 Make_Range (Loc,
5841 Low_Bound =>
5842 Make_Attribute_Reference (Loc,
5843 Attribute_Name => Name_First,
e4494292 5844 Prefix => New_Occurrence_Of (Typ, Loc)),
c7532b2d
AC
5845
5846 High_Bound =>
5847 Make_Attribute_Reference (Loc,
5848 Attribute_Name => Name_Last,
e4494292 5849 Prefix => New_Occurrence_Of (Typ, Loc))));
c7532b2d
AC
5850 Analyze_And_Resolve (N, Restyp);
5851 end if;
70482933 5852
4818e7b9 5853 goto Leave;
5d09245e
AC
5854
5855 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
5856 -- a membership test if the subtype mark denotes a constrained
5857 -- Unchecked_Union subtype and the expression lacks inferable
5858 -- discriminants.
5859
5860 elsif Is_Unchecked_Union (Base_Type (Typ))
5861 and then Is_Constrained (Typ)
5862 and then not Has_Inferable_Discriminants (Lop)
5863 then
5864 Insert_Action (N,
5865 Make_Raise_Program_Error (Loc,
5866 Reason => PE_Unchecked_Union_Restriction));
5867
9a0ddeee 5868 -- Prevent Gigi from generating incorrect code by rewriting the
f6194278 5869 -- test as False. What is this undocumented thing about ???
5d09245e 5870
9a0ddeee 5871 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
4818e7b9 5872 goto Leave;
70482933
RK
5873 end if;
5874
fbf5a39b
AC
5875 -- Here we have a non-scalar type
5876
70482933
RK
5877 if Is_Acc then
5878 Typ := Designated_Type (Typ);
5879 end if;
5880
5881 if not Is_Constrained (Typ) then
e4494292 5882 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
4818e7b9 5883 Analyze_And_Resolve (N, Restyp);
70482933 5884
685094bf
RD
5885 -- For the constrained array case, we have to check the subscripts
5886 -- for an exact match if the lengths are non-zero (the lengths
5887 -- must match in any case).
70482933
RK
5888
5889 elsif Is_Array_Type (Typ) then
fbf5a39b 5890 Check_Subscripts : declare
9a0ddeee 5891 function Build_Attribute_Reference
2e071734
AC
5892 (E : Node_Id;
5893 Nam : Name_Id;
5894 Dim : Nat) return Node_Id;
9a0ddeee 5895 -- Build attribute reference E'Nam (Dim)
70482933 5896
9a0ddeee
AC
5897 -------------------------------
5898 -- Build_Attribute_Reference --
5899 -------------------------------
fbf5a39b 5900
9a0ddeee 5901 function Build_Attribute_Reference
2e071734
AC
5902 (E : Node_Id;
5903 Nam : Name_Id;
5904 Dim : Nat) return Node_Id
70482933
RK
5905 is
5906 begin
5907 return
5908 Make_Attribute_Reference (Loc,
9a0ddeee 5909 Prefix => E,
70482933 5910 Attribute_Name => Nam,
9a0ddeee 5911 Expressions => New_List (
70482933 5912 Make_Integer_Literal (Loc, Dim)));
9a0ddeee 5913 end Build_Attribute_Reference;
70482933 5914
fad0600d 5915 -- Start of processing for Check_Subscripts
fbf5a39b 5916
70482933
RK
5917 begin
5918 for J in 1 .. Number_Dimensions (Typ) loop
5919 Evolve_And_Then (Cond,
5920 Make_Op_Eq (Loc,
5921 Left_Opnd =>
9a0ddeee 5922 Build_Attribute_Reference
fbf5a39b
AC
5923 (Duplicate_Subexpr_No_Checks (Obj),
5924 Name_First, J),
70482933 5925 Right_Opnd =>
9a0ddeee 5926 Build_Attribute_Reference
70482933
RK
5927 (New_Occurrence_Of (Typ, Loc), Name_First, J)));
5928
5929 Evolve_And_Then (Cond,
5930 Make_Op_Eq (Loc,
5931 Left_Opnd =>
9a0ddeee 5932 Build_Attribute_Reference
fbf5a39b
AC
5933 (Duplicate_Subexpr_No_Checks (Obj),
5934 Name_Last, J),
70482933 5935 Right_Opnd =>
9a0ddeee 5936 Build_Attribute_Reference
70482933
RK
5937 (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
5938 end loop;
5939
5940 if Is_Acc then
fbf5a39b
AC
5941 Cond :=
5942 Make_Or_Else (Loc,
cc6f5d75 5943 Left_Opnd =>
fbf5a39b
AC
5944 Make_Op_Eq (Loc,
5945 Left_Opnd => Obj,
5946 Right_Opnd => Make_Null (Loc)),
5947 Right_Opnd => Cond);
70482933
RK
5948 end if;
5949
5950 Rewrite (N, Cond);
4818e7b9 5951 Analyze_And_Resolve (N, Restyp);
fbf5a39b 5952 end Check_Subscripts;
70482933 5953
685094bf
RD
5954 -- These are the cases where constraint checks may be required,
5955 -- e.g. records with possible discriminants
70482933
RK
5956
5957 else
5958 -- Expand the test into a series of discriminant comparisons.
685094bf
RD
5959 -- The expression that is built is the negation of the one that
5960 -- is used for checking discriminant constraints.
70482933
RK
5961
5962 Obj := Relocate_Node (Left_Opnd (N));
5963
5964 if Has_Discriminants (Typ) then
5965 Cond := Make_Op_Not (Loc,
5966 Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
5967
5968 if Is_Acc then
5969 Cond := Make_Or_Else (Loc,
cc6f5d75 5970 Left_Opnd =>
70482933
RK
5971 Make_Op_Eq (Loc,
5972 Left_Opnd => Obj,
5973 Right_Opnd => Make_Null (Loc)),
5974 Right_Opnd => Cond);
5975 end if;
5976
5977 else
5978 Cond := New_Occurrence_Of (Standard_True, Loc);
5979 end if;
5980
5981 Rewrite (N, Cond);
4818e7b9 5982 Analyze_And_Resolve (N, Restyp);
70482933 5983 end if;
6cce2156
GD
5984
5985 -- Ada 2012 (AI05-0149): Handle membership tests applied to an
5986 -- expression of an anonymous access type. This can involve an
5987 -- accessibility test and a tagged type membership test in the
5988 -- case of tagged designated types.
5989
5990 if Ada_Version >= Ada_2012
5991 and then Is_Acc
5992 and then Ekind (Ltyp) = E_Anonymous_Access_Type
5993 then
5994 declare
5995 Expr_Entity : Entity_Id := Empty;
5996 New_N : Node_Id;
5997 Param_Level : Node_Id;
5998 Type_Level : Node_Id;
996c8821 5999
6cce2156
GD
6000 begin
6001 if Is_Entity_Name (Lop) then
6002 Expr_Entity := Param_Entity (Lop);
996c8821 6003
6cce2156
GD
6004 if not Present (Expr_Entity) then
6005 Expr_Entity := Entity (Lop);
6006 end if;
6007 end if;
6008
6009 -- If a conversion of the anonymous access value to the
6010 -- tested type would be illegal, then the result is False.
6011
6012 if not Valid_Conversion
6013 (Lop, Rtyp, Lop, Report_Errs => False)
6014 then
6015 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
6016 Analyze_And_Resolve (N, Restyp);
6017
6018 -- Apply an accessibility check if the access object has an
6019 -- associated access level and when the level of the type is
6020 -- less deep than the level of the access parameter. This
6021 -- only occur for access parameters and stand-alone objects
6022 -- of an anonymous access type.
6023
6024 else
6025 if Present (Expr_Entity)
996c8821
RD
6026 and then
6027 Present
6028 (Effective_Extra_Accessibility (Expr_Entity))
6029 and then UI_Gt (Object_Access_Level (Lop),
6030 Type_Access_Level (Rtyp))
6cce2156
GD
6031 then
6032 Param_Level :=
6033 New_Occurrence_Of
d15f9422 6034 (Effective_Extra_Accessibility (Expr_Entity), Loc);
6cce2156
GD
6035
6036 Type_Level :=
6037 Make_Integer_Literal (Loc, Type_Access_Level (Rtyp));
6038
6039 -- Return True only if the accessibility level of the
6040 -- expression entity is not deeper than the level of
6041 -- the tested access type.
6042
6043 Rewrite (N,
6044 Make_And_Then (Loc,
6045 Left_Opnd => Relocate_Node (N),
6046 Right_Opnd => Make_Op_Le (Loc,
6047 Left_Opnd => Param_Level,
6048 Right_Opnd => Type_Level)));
6049
6050 Analyze_And_Resolve (N);
6051 end if;
6052
6053 -- If the designated type is tagged, do tagged membership
6054 -- operation.
6055
6056 -- *** NOTE: we have to check not null before doing the
6057 -- tagged membership test (but maybe that can be done
6058 -- inside Tagged_Membership?).
6059
6060 if Is_Tagged_Type (Typ) then
6061 Rewrite (N,
6062 Make_And_Then (Loc,
6063 Left_Opnd => Relocate_Node (N),
6064 Right_Opnd =>
6065 Make_Op_Ne (Loc,
6066 Left_Opnd => Obj,
6067 Right_Opnd => Make_Null (Loc))));
6068
6069 -- No expansion will be performed when VM_Target, as
6070 -- the VM back-ends will handle the membership tests
6071 -- directly (tags are not explicitly represented in
6072 -- Java objects, so the normal tagged membership
6073 -- expansion is not what we want).
6074
6075 if Tagged_Type_Expansion then
6076
6077 -- Note that we have to pass Original_Node, because
6078 -- the membership test might already have been
6079 -- rewritten by earlier parts of membership test.
6080
6081 Tagged_Membership
6082 (Original_Node (N), SCIL_Node, New_N);
6083
6084 -- Update decoration of relocated node referenced
6085 -- by the SCIL node.
6086
6087 if Generate_SCIL and then Present (SCIL_Node) then
6088 Set_SCIL_Node (New_N, SCIL_Node);
6089 end if;
6090
6091 Rewrite (N,
6092 Make_And_Then (Loc,
6093 Left_Opnd => Relocate_Node (N),
6094 Right_Opnd => New_N));
6095
6096 Analyze_And_Resolve (N, Restyp);
6097 end if;
6098 end if;
6099 end if;
6100 end;
6101 end if;
70482933
RK
6102 end;
6103 end if;
4818e7b9
RD
6104
6105 -- At this point, we have done the processing required for the basic
6106 -- membership test, but not yet dealt with the predicate.
6107
6108 <<Leave>>
6109
c7532b2d
AC
6110 -- If a predicate is present, then we do the predicate test, but we
6111 -- most certainly want to omit this if we are within the predicate
a90bd866 6112 -- function itself, since otherwise we have an infinite recursion.
3d6db7f8
GD
6113 -- The check should also not be emitted when testing against a range
6114 -- (the check is only done when the right operand is a subtype; see
6115 -- RM12-4.5.2 (28.1/3-30/3)).
4818e7b9 6116
c7532b2d
AC
6117 declare
6118 PFunc : constant Entity_Id := Predicate_Function (Rtyp);
4818e7b9 6119
c7532b2d
AC
6120 begin
6121 if Present (PFunc)
6122 and then Current_Scope /= PFunc
3d6db7f8 6123 and then Nkind (Rop) /= N_Range
c7532b2d
AC
6124 then
6125 Rewrite (N,
6126 Make_And_Then (Loc,
6127 Left_Opnd => Relocate_Node (N),
fc142f63 6128 Right_Opnd => Make_Predicate_Call (Rtyp, Lop, Mem => True)));
4818e7b9 6129
c7532b2d 6130 -- Analyze new expression, mark left operand as analyzed to
b2009d46
AC
6131 -- avoid infinite recursion adding predicate calls. Similarly,
6132 -- suppress further range checks on the call.
4818e7b9 6133
c7532b2d 6134 Set_Analyzed (Left_Opnd (N));
b2009d46 6135 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
4818e7b9 6136
c7532b2d
AC
6137 -- All done, skip attempt at compile time determination of result
6138
6139 return;
6140 end if;
6141 end;
70482933
RK
6142 end Expand_N_In;
6143
6144 --------------------------------
6145 -- Expand_N_Indexed_Component --
6146 --------------------------------
6147
6148 procedure Expand_N_Indexed_Component (N : Node_Id) is
6149 Loc : constant Source_Ptr := Sloc (N);
6150 Typ : constant Entity_Id := Etype (N);
6151 P : constant Node_Id := Prefix (N);
6152 T : constant Entity_Id := Etype (P);
5972791c 6153 Atp : Entity_Id;
70482933
RK
6154
6155 begin
685094bf
RD
6156 -- A special optimization, if we have an indexed component that is
6157 -- selecting from a slice, then we can eliminate the slice, since, for
6158 -- example, x (i .. j)(k) is identical to x(k). The only difference is
6159 -- the range check required by the slice. The range check for the slice
6160 -- itself has already been generated. The range check for the
6161 -- subscripting operation is ensured by converting the subject to
6162 -- the subtype of the slice.
6163
6164 -- This optimization not only generates better code, avoiding slice
6165 -- messing especially in the packed case, but more importantly bypasses
6166 -- some problems in handling this peculiar case, for example, the issue
6167 -- of dealing specially with object renamings.
70482933 6168
45ec05e1
RD
6169 if Nkind (P) = N_Slice
6170
6171 -- This optimization is disabled for CodePeer because it can transform
6172 -- an index-check constraint_error into a range-check constraint_error
6173 -- and CodePeer cares about that distinction.
6174
6175 and then not CodePeer_Mode
6176 then
70482933
RK
6177 Rewrite (N,
6178 Make_Indexed_Component (Loc,
cc6f5d75 6179 Prefix => Prefix (P),
70482933
RK
6180 Expressions => New_List (
6181 Convert_To
6182 (Etype (First_Index (Etype (P))),
6183 First (Expressions (N))))));
6184 Analyze_And_Resolve (N, Typ);
6185 return;
6186 end if;
6187
b4592168
GD
6188 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
6189 -- function, then additional actuals must be passed.
6190
0791fbe9 6191 if Ada_Version >= Ada_2005
b4592168
GD
6192 and then Is_Build_In_Place_Function_Call (P)
6193 then
6194 Make_Build_In_Place_Call_In_Anonymous_Context (P);
6195 end if;
6196
685094bf 6197 -- If the prefix is an access type, then we unconditionally rewrite if
09494c32 6198 -- as an explicit dereference. This simplifies processing for several
685094bf
RD
6199 -- cases, including packed array cases and certain cases in which checks
6200 -- must be generated. We used to try to do this only when it was
6201 -- necessary, but it cleans up the code to do it all the time.
70482933
RK
6202
6203 if Is_Access_Type (T) then
2717634d 6204 Insert_Explicit_Dereference (P);
70482933 6205 Analyze_And_Resolve (P, Designated_Type (T));
5972791c
AC
6206 Atp := Designated_Type (T);
6207 else
6208 Atp := T;
70482933
RK
6209 end if;
6210
fbf5a39b
AC
6211 -- Generate index and validity checks
6212
6213 Generate_Index_Checks (N);
6214
70482933
RK
6215 if Validity_Checks_On and then Validity_Check_Subscripts then
6216 Apply_Subscript_Validity_Checks (N);
6217 end if;
6218
5972791c
AC
6219 -- If selecting from an array with atomic components, and atomic sync
6220 -- is not suppressed for this array type, set atomic sync flag.
6221
6222 if (Has_Atomic_Components (Atp)
6223 and then not Atomic_Synchronization_Disabled (Atp))
6224 or else (Is_Atomic (Typ)
6225 and then not Atomic_Synchronization_Disabled (Typ))
6226 then
4c318253 6227 Activate_Atomic_Synchronization (N);
5972791c
AC
6228 end if;
6229
70482933
RK
6230 -- All done for the non-packed case
6231
6232 if not Is_Packed (Etype (Prefix (N))) then
6233 return;
6234 end if;
6235
6236 -- For packed arrays that are not bit-packed (i.e. the case of an array
8fc789c8 6237 -- with one or more index types with a non-contiguous enumeration type),
70482933
RK
6238 -- we can always use the normal packed element get circuit.
6239
6240 if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
6241 Expand_Packed_Element_Reference (N);
6242 return;
6243 end if;
6244
8ca597af
RD
6245 -- For a reference to a component of a bit packed array, we convert it
6246 -- to a reference to the corresponding Packed_Array_Impl_Type. We only
6247 -- want to do this for simple references, and not for:
70482933 6248
685094bf
RD
6249 -- Left side of assignment, or prefix of left side of assignment, or
6250 -- prefix of the prefix, to handle packed arrays of packed arrays,
70482933
RK
6251 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
6252
6253 -- Renaming objects in renaming associations
6254 -- This case is handled when a use of the renamed variable occurs
6255
6256 -- Actual parameters for a procedure call
6257 -- This case is handled in Exp_Ch6.Expand_Actuals
6258
6259 -- The second expression in a 'Read attribute reference
6260
47d3b920 6261 -- The prefix of an address or bit or size attribute reference
70482933
RK
6262
6263 -- The following circuit detects these exceptions
6264
6265 declare
6266 Child : Node_Id := N;
6267 Parnt : Node_Id := Parent (N);
6268
6269 begin
6270 loop
6271 if Nkind (Parnt) = N_Unchecked_Expression then
6272 null;
6273
303b4d58
AC
6274 elsif Nkind_In (Parnt, N_Object_Renaming_Declaration,
6275 N_Procedure_Call_Statement)
70482933
RK
6276 or else (Nkind (Parnt) = N_Parameter_Association
6277 and then
6278 Nkind (Parent (Parnt)) = N_Procedure_Call_Statement)
6279 then
6280 return;
6281
6282 elsif Nkind (Parnt) = N_Attribute_Reference
b69cd36a
AC
6283 and then Nam_In (Attribute_Name (Parnt), Name_Address,
6284 Name_Bit,
6285 Name_Size)
70482933
RK
6286 and then Prefix (Parnt) = Child
6287 then
6288 return;
6289
6290 elsif Nkind (Parnt) = N_Assignment_Statement
6291 and then Name (Parnt) = Child
6292 then
6293 return;
6294
685094bf
RD
6295 -- If the expression is an index of an indexed component, it must
6296 -- be expanded regardless of context.
fbf5a39b
AC
6297
6298 elsif Nkind (Parnt) = N_Indexed_Component
6299 and then Child /= Prefix (Parnt)
6300 then
6301 Expand_Packed_Element_Reference (N);
6302 return;
6303
6304 elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
6305 and then Name (Parent (Parnt)) = Parnt
6306 then
6307 return;
6308
70482933
RK
6309 elsif Nkind (Parnt) = N_Attribute_Reference
6310 and then Attribute_Name (Parnt) = Name_Read
6311 and then Next (First (Expressions (Parnt))) = Child
6312 then
6313 return;
6314
303b4d58 6315 elsif Nkind_In (Parnt, N_Indexed_Component, N_Selected_Component)
533369aa 6316 and then Prefix (Parnt) = Child
70482933
RK
6317 then
6318 null;
6319
6320 else
6321 Expand_Packed_Element_Reference (N);
6322 return;
6323 end if;
6324
685094bf
RD
6325 -- Keep looking up tree for unchecked expression, or if we are the
6326 -- prefix of a possible assignment left side.
70482933
RK
6327
6328 Child := Parnt;
6329 Parnt := Parent (Child);
6330 end loop;
6331 end;
70482933
RK
6332 end Expand_N_Indexed_Component;
6333
6334 ---------------------
6335 -- Expand_N_Not_In --
6336 ---------------------
6337
6338 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
6339 -- can be done. This avoids needing to duplicate this expansion code.
6340
6341 procedure Expand_N_Not_In (N : Node_Id) is
630d30e9
RD
6342 Loc : constant Source_Ptr := Sloc (N);
6343 Typ : constant Entity_Id := Etype (N);
6344 Cfs : constant Boolean := Comes_From_Source (N);
70482933
RK
6345
6346 begin
6347 Rewrite (N,
6348 Make_Op_Not (Loc,
6349 Right_Opnd =>
6350 Make_In (Loc,
6351 Left_Opnd => Left_Opnd (N),
d766cee3 6352 Right_Opnd => Right_Opnd (N))));
630d30e9 6353
197e4514
AC
6354 -- If this is a set membership, preserve list of alternatives
6355
6356 Set_Alternatives (Right_Opnd (N), Alternatives (Original_Node (N)));
6357
d766cee3 6358 -- We want this to appear as coming from source if original does (see
8fc789c8 6359 -- transformations in Expand_N_In).
630d30e9
RD
6360
6361 Set_Comes_From_Source (N, Cfs);
6362 Set_Comes_From_Source (Right_Opnd (N), Cfs);
6363
8fc789c8 6364 -- Now analyze transformed node
630d30e9 6365
70482933
RK
6366 Analyze_And_Resolve (N, Typ);
6367 end Expand_N_Not_In;
6368
6369 -------------------
6370 -- Expand_N_Null --
6371 -------------------
6372
a3f2babd
AC
6373 -- The only replacement required is for the case of a null of a type that
6374 -- is an access to protected subprogram, or a subtype thereof. We represent
6375 -- such access values as a record, and so we must replace the occurrence of
6376 -- null by the equivalent record (with a null address and a null pointer in
6377 -- it), so that the backend creates the proper value.
70482933
RK
6378
6379 procedure Expand_N_Null (N : Node_Id) is
6380 Loc : constant Source_Ptr := Sloc (N);
a3f2babd 6381 Typ : constant Entity_Id := Base_Type (Etype (N));
70482933
RK
6382 Agg : Node_Id;
6383
6384 begin
26bff3d9 6385 if Is_Access_Protected_Subprogram_Type (Typ) then
70482933
RK
6386 Agg :=
6387 Make_Aggregate (Loc,
6388 Expressions => New_List (
6389 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
6390 Make_Null (Loc)));
6391
6392 Rewrite (N, Agg);
6393 Analyze_And_Resolve (N, Equivalent_Type (Typ));
6394
685094bf
RD
6395 -- For subsequent semantic analysis, the node must retain its type.
6396 -- Gigi in any case replaces this type by the corresponding record
6397 -- type before processing the node.
70482933
RK
6398
6399 Set_Etype (N, Typ);
6400 end if;
fbf5a39b
AC
6401
6402 exception
6403 when RE_Not_Available =>
6404 return;
70482933
RK
6405 end Expand_N_Null;
6406
6407 ---------------------
6408 -- Expand_N_Op_Abs --
6409 ---------------------
6410
6411 procedure Expand_N_Op_Abs (N : Node_Id) is
6412 Loc : constant Source_Ptr := Sloc (N);
cc6f5d75 6413 Expr : constant Node_Id := Right_Opnd (N);
70482933
RK
6414
6415 begin
6416 Unary_Op_Validity_Checks (N);
6417
b6b5cca8
AC
6418 -- Check for MINIMIZED/ELIMINATED overflow mode
6419
6420 if Minimized_Eliminated_Overflow_Check (N) then
6421 Apply_Arithmetic_Overflow_Check (N);
6422 return;
6423 end if;
6424
70482933
RK
6425 -- Deal with software overflow checking
6426
07fc65c4 6427 if not Backend_Overflow_Checks_On_Target
533369aa
AC
6428 and then Is_Signed_Integer_Type (Etype (N))
6429 and then Do_Overflow_Check (N)
70482933 6430 then
685094bf
RD
6431 -- The only case to worry about is when the argument is equal to the
6432 -- largest negative number, so what we do is to insert the check:
70482933 6433
fbf5a39b 6434 -- [constraint_error when Expr = typ'Base'First]
70482933
RK
6435
6436 -- with the usual Duplicate_Subexpr use coding for expr
6437
fbf5a39b
AC
6438 Insert_Action (N,
6439 Make_Raise_Constraint_Error (Loc,
6440 Condition =>
6441 Make_Op_Eq (Loc,
70482933 6442 Left_Opnd => Duplicate_Subexpr (Expr),
fbf5a39b
AC
6443 Right_Opnd =>
6444 Make_Attribute_Reference (Loc,
cc6f5d75 6445 Prefix =>
fbf5a39b
AC
6446 New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
6447 Attribute_Name => Name_First)),
6448 Reason => CE_Overflow_Check_Failed));
6449 end if;
70482933
RK
6450 end Expand_N_Op_Abs;
6451
6452 ---------------------
6453 -- Expand_N_Op_Add --
6454 ---------------------
6455
6456 procedure Expand_N_Op_Add (N : Node_Id) is
6457 Typ : constant Entity_Id := Etype (N);
6458
6459 begin
6460 Binary_Op_Validity_Checks (N);
6461
b6b5cca8
AC
6462 -- Check for MINIMIZED/ELIMINATED overflow mode
6463
6464 if Minimized_Eliminated_Overflow_Check (N) then
6465 Apply_Arithmetic_Overflow_Check (N);
6466 return;
6467 end if;
6468
70482933
RK
6469 -- N + 0 = 0 + N = N for integer types
6470
6471 if Is_Integer_Type (Typ) then
6472 if Compile_Time_Known_Value (Right_Opnd (N))
6473 and then Expr_Value (Right_Opnd (N)) = Uint_0
6474 then
6475 Rewrite (N, Left_Opnd (N));
6476 return;
6477
6478 elsif Compile_Time_Known_Value (Left_Opnd (N))
6479 and then Expr_Value (Left_Opnd (N)) = Uint_0
6480 then
6481 Rewrite (N, Right_Opnd (N));
6482 return;
6483 end if;
6484 end if;
6485
fbf5a39b 6486 -- Arithmetic overflow checks for signed integer/fixed point types
70482933 6487
761f7dcb 6488 if Is_Signed_Integer_Type (Typ) or else Is_Fixed_Point_Type (Typ) then
70482933
RK
6489 Apply_Arithmetic_Overflow_Check (N);
6490 return;
70482933 6491 end if;
dfaff97b
RD
6492
6493 -- Overflow checks for floating-point if -gnateF mode active
6494
6495 Check_Float_Op_Overflow (N);
70482933
RK
6496 end Expand_N_Op_Add;
6497
6498 ---------------------
6499 -- Expand_N_Op_And --
6500 ---------------------
6501
6502 procedure Expand_N_Op_And (N : Node_Id) is
6503 Typ : constant Entity_Id := Etype (N);
6504
6505 begin
6506 Binary_Op_Validity_Checks (N);
6507
6508 if Is_Array_Type (Etype (N)) then
6509 Expand_Boolean_Operator (N);
6510
6511 elsif Is_Boolean_Type (Etype (N)) then
f2d10a02
AC
6512 Adjust_Condition (Left_Opnd (N));
6513 Adjust_Condition (Right_Opnd (N));
6514 Set_Etype (N, Standard_Boolean);
6515 Adjust_Result_Type (N, Typ);
437f8c1e
AC
6516
6517 elsif Is_Intrinsic_Subprogram (Entity (N)) then
6518 Expand_Intrinsic_Call (N, Entity (N));
6519
70482933
RK
6520 end if;
6521 end Expand_N_Op_And;
6522
6523 ------------------------
6524 -- Expand_N_Op_Concat --
6525 ------------------------
6526
6527 procedure Expand_N_Op_Concat (N : Node_Id) is
70482933
RK
6528 Opnds : List_Id;
6529 -- List of operands to be concatenated
6530
70482933 6531 Cnode : Node_Id;
685094bf
RD
6532 -- Node which is to be replaced by the result of concatenating the nodes
6533 -- in the list Opnds.
70482933 6534
70482933 6535 begin
fbf5a39b
AC
6536 -- Ensure validity of both operands
6537
70482933
RK
6538 Binary_Op_Validity_Checks (N);
6539
685094bf
RD
6540 -- If we are the left operand of a concatenation higher up the tree,
6541 -- then do nothing for now, since we want to deal with a series of
6542 -- concatenations as a unit.
70482933
RK
6543
6544 if Nkind (Parent (N)) = N_Op_Concat
6545 and then N = Left_Opnd (Parent (N))
6546 then
6547 return;
6548 end if;
6549
6550 -- We get here with a concatenation whose left operand may be a
6551 -- concatenation itself with a consistent type. We need to process
6552 -- these concatenation operands from left to right, which means
6553 -- from the deepest node in the tree to the highest node.
6554
6555 Cnode := N;
6556 while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
6557 Cnode := Left_Opnd (Cnode);
6558 end loop;
6559
64425dff
BD
6560 -- Now Cnode is the deepest concatenation, and its parents are the
6561 -- concatenation nodes above, so now we process bottom up, doing the
64425dff 6562 -- operands.
70482933 6563
df46b832
AC
6564 -- The outer loop runs more than once if more than one concatenation
6565 -- type is involved.
70482933
RK
6566
6567 Outer : loop
6568 Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
6569 Set_Parent (Opnds, N);
6570
df46b832 6571 -- The inner loop gathers concatenation operands
70482933
RK
6572
6573 Inner : while Cnode /= N
70482933
RK
6574 and then Base_Type (Etype (Cnode)) =
6575 Base_Type (Etype (Parent (Cnode)))
6576 loop
6577 Cnode := Parent (Cnode);
6578 Append (Right_Opnd (Cnode), Opnds);
6579 end loop Inner;
6580
43c58950
AC
6581 -- Note: The following code is a temporary workaround for N731-034
6582 -- and N829-028 and will be kept until the general issue of internal
6583 -- symbol serialization is addressed. The workaround is kept under a
6584 -- debug switch to avoid permiating into the general case.
6585
6586 -- Wrap the node to concatenate into an expression actions node to
6587 -- keep it nicely packaged. This is useful in the case of an assert
6588 -- pragma with a concatenation where we want to be able to delete
6589 -- the concatenation and all its expansion stuff.
6590
6591 if Debug_Flag_Dot_H then
6592 declare
6593 Cnod : constant Node_Id := Relocate_Node (Cnode);
6594 Typ : constant Entity_Id := Base_Type (Etype (Cnode));
6595
6596 begin
6597 -- Note: use Rewrite rather than Replace here, so that for
6598 -- example Why_Not_Static can find the original concatenation
6599 -- node OK!
6600
6601 Rewrite (Cnode,
6602 Make_Expression_With_Actions (Sloc (Cnode),
6603 Actions => New_List (Make_Null_Statement (Sloc (Cnode))),
6604 Expression => Cnod));
6605
6606 Expand_Concatenate (Cnod, Opnds);
6607 Analyze_And_Resolve (Cnode, Typ);
6608 end;
6609
6610 -- Default case
6611
6612 else
6613 Expand_Concatenate (Cnode, Opnds);
6614 end if;
70482933
RK
6615
6616 exit Outer when Cnode = N;
6617 Cnode := Parent (Cnode);
6618 end loop Outer;
6619 end Expand_N_Op_Concat;
6620
6621 ------------------------
6622 -- Expand_N_Op_Divide --
6623 ------------------------
6624
6625 procedure Expand_N_Op_Divide (N : Node_Id) is
f82944b7
JM
6626 Loc : constant Source_Ptr := Sloc (N);
6627 Lopnd : constant Node_Id := Left_Opnd (N);
6628 Ropnd : constant Node_Id := Right_Opnd (N);
6629 Ltyp : constant Entity_Id := Etype (Lopnd);
6630 Rtyp : constant Entity_Id := Etype (Ropnd);
6631 Typ : Entity_Id := Etype (N);
6632 Rknow : constant Boolean := Is_Integer_Type (Typ)
6633 and then
6634 Compile_Time_Known_Value (Ropnd);
6635 Rval : Uint;
70482933
RK
6636
6637 begin
6638 Binary_Op_Validity_Checks (N);
6639
b6b5cca8
AC
6640 -- Check for MINIMIZED/ELIMINATED overflow mode
6641
6642 if Minimized_Eliminated_Overflow_Check (N) then
6643 Apply_Arithmetic_Overflow_Check (N);
6644 return;
6645 end if;
6646
6647 -- Otherwise proceed with expansion of division
6648
f82944b7
JM
6649 if Rknow then
6650 Rval := Expr_Value (Ropnd);
6651 end if;
6652
70482933
RK
6653 -- N / 1 = N for integer types
6654
f82944b7
JM
6655 if Rknow and then Rval = Uint_1 then
6656 Rewrite (N, Lopnd);
70482933
RK
6657 return;
6658 end if;
6659
6660 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
6661 -- Is_Power_Of_2_For_Shift is set means that we know that our left
6662 -- operand is an unsigned integer, as required for this to work.
6663
f82944b7
JM
6664 if Nkind (Ropnd) = N_Op_Expon
6665 and then Is_Power_Of_2_For_Shift (Ropnd)
fbf5a39b
AC
6666
6667 -- We cannot do this transformation in configurable run time mode if we
51bf9bdf 6668 -- have 64-bit integers and long shifts are not available.
fbf5a39b 6669
761f7dcb 6670 and then (Esize (Ltyp) <= 32 or else Support_Long_Shifts_On_Target)
70482933
RK
6671 then
6672 Rewrite (N,
6673 Make_Op_Shift_Right (Loc,
f82944b7 6674 Left_Opnd => Lopnd,
70482933 6675 Right_Opnd =>
f82944b7 6676 Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
70482933
RK
6677 Analyze_And_Resolve (N, Typ);
6678 return;
6679 end if;
6680
6681 -- Do required fixup of universal fixed operation
6682
6683 if Typ = Universal_Fixed then
6684 Fixup_Universal_Fixed_Operation (N);
6685 Typ := Etype (N);
6686 end if;
6687
6688 -- Divisions with fixed-point results
6689
6690 if Is_Fixed_Point_Type (Typ) then
6691
21f30884
AC
6692 -- Deal with divide-by-zero check if back end cannot handle them
6693 -- and the flag is set indicating that we need such a check. Note
6694 -- that we don't need to bother here with the case of mixed-mode
6695 -- (Right operand an integer type), since these will be rewritten
6696 -- with conversions to a divide with a fixed-point right operand.
6697
6698 if Do_Division_Check (N)
6699 and then not Backend_Divide_Checks_On_Target
6700 and then not Is_Integer_Type (Rtyp)
6701 then
6702 Set_Do_Division_Check (N, False);
6703 Insert_Action (N,
6704 Make_Raise_Constraint_Error (Loc,
6705 Condition =>
6706 Make_Op_Eq (Loc,
6707 Left_Opnd => Duplicate_Subexpr_Move_Checks (Ropnd),
6708 Right_Opnd => Make_Real_Literal (Loc, Ureal_0)),
6709 Reason => CE_Divide_By_Zero));
6710 end if;
6711
685094bf
RD
6712 -- No special processing if Treat_Fixed_As_Integer is set, since
6713 -- from a semantic point of view such operations are simply integer
6714 -- operations and will be treated that way.
70482933
RK
6715
6716 if not Treat_Fixed_As_Integer (N) then
6717 if Is_Integer_Type (Rtyp) then
6718 Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
6719 else
6720 Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
6721 end if;
6722 end if;
6723
685094bf
RD
6724 -- Other cases of division of fixed-point operands. Again we exclude the
6725 -- case where Treat_Fixed_As_Integer is set.
70482933 6726
761f7dcb 6727 elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
70482933
RK
6728 and then not Treat_Fixed_As_Integer (N)
6729 then
6730 if Is_Integer_Type (Typ) then
6731 Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
6732 else
6733 pragma Assert (Is_Floating_Point_Type (Typ));
6734 Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
6735 end if;
6736
685094bf
RD
6737 -- Mixed-mode operations can appear in a non-static universal context,
6738 -- in which case the integer argument must be converted explicitly.
70482933 6739
533369aa 6740 elsif Typ = Universal_Real and then Is_Integer_Type (Rtyp) then
f82944b7
JM
6741 Rewrite (Ropnd,
6742 Convert_To (Universal_Real, Relocate_Node (Ropnd)));
70482933 6743
f82944b7 6744 Analyze_And_Resolve (Ropnd, Universal_Real);
70482933 6745
533369aa 6746 elsif Typ = Universal_Real and then Is_Integer_Type (Ltyp) then
f82944b7
JM
6747 Rewrite (Lopnd,
6748 Convert_To (Universal_Real, Relocate_Node (Lopnd)));
70482933 6749
f82944b7 6750 Analyze_And_Resolve (Lopnd, Universal_Real);
70482933 6751
f02b8bb8 6752 -- Non-fixed point cases, do integer zero divide and overflow checks
70482933
RK
6753
6754 elsif Is_Integer_Type (Typ) then
a91e9ac7 6755 Apply_Divide_Checks (N);
70482933 6756 end if;
dfaff97b
RD
6757
6758 -- Overflow checks for floating-point if -gnateF mode active
6759
6760 Check_Float_Op_Overflow (N);
70482933
RK
6761 end Expand_N_Op_Divide;
6762
6763 --------------------
6764 -- Expand_N_Op_Eq --
6765 --------------------
6766
6767 procedure Expand_N_Op_Eq (N : Node_Id) is
fbf5a39b
AC
6768 Loc : constant Source_Ptr := Sloc (N);
6769 Typ : constant Entity_Id := Etype (N);
6770 Lhs : constant Node_Id := Left_Opnd (N);
6771 Rhs : constant Node_Id := Right_Opnd (N);
6772 Bodies : constant List_Id := New_List;
6773 A_Typ : constant Entity_Id := Etype (Lhs);
6774
70482933
RK
6775 Typl : Entity_Id := A_Typ;
6776 Op_Name : Entity_Id;
6777 Prim : Elmt_Id;
70482933
RK
6778
6779 procedure Build_Equality_Call (Eq : Entity_Id);
6780 -- If a constructed equality exists for the type or for its parent,
6781 -- build and analyze call, adding conversions if the operation is
6782 -- inherited.
6783
5d09245e 6784 function Has_Unconstrained_UU_Component (Typ : Node_Id) return Boolean;
8fc789c8 6785 -- Determines whether a type has a subcomponent of an unconstrained
5d09245e
AC
6786 -- Unchecked_Union subtype. Typ is a record type.
6787
70482933
RK
6788 -------------------------
6789 -- Build_Equality_Call --
6790 -------------------------
6791
6792 procedure Build_Equality_Call (Eq : Entity_Id) is
6793 Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
cc6f5d75
AC
6794 L_Exp : Node_Id := Relocate_Node (Lhs);
6795 R_Exp : Node_Id := Relocate_Node (Rhs);
70482933
RK
6796
6797 begin
dda38714
AC
6798 -- Adjust operands if necessary to comparison type
6799
70482933
RK
6800 if Base_Type (Op_Type) /= Base_Type (A_Typ)
6801 and then not Is_Class_Wide_Type (A_Typ)
6802 then
6803 L_Exp := OK_Convert_To (Op_Type, L_Exp);
6804 R_Exp := OK_Convert_To (Op_Type, R_Exp);
6805 end if;
6806
5d09245e
AC
6807 -- If we have an Unchecked_Union, we need to add the inferred
6808 -- discriminant values as actuals in the function call. At this
6809 -- point, the expansion has determined that both operands have
6810 -- inferable discriminants.
6811
6812 if Is_Unchecked_Union (Op_Type) then
6813 declare
fa1608c2
ES
6814 Lhs_Type : constant Node_Id := Etype (L_Exp);
6815 Rhs_Type : constant Node_Id := Etype (R_Exp);
6816
6817 Lhs_Discr_Vals : Elist_Id;
6818 -- List of inferred discriminant values for left operand.
6819
6820 Rhs_Discr_Vals : Elist_Id;
6821 -- List of inferred discriminant values for right operand.
6822
6823 Discr : Entity_Id;
5d09245e
AC
6824
6825 begin
fa1608c2
ES
6826 Lhs_Discr_Vals := New_Elmt_List;
6827 Rhs_Discr_Vals := New_Elmt_List;
6828
5d09245e
AC
6829 -- Per-object constrained selected components require special
6830 -- attention. If the enclosing scope of the component is an
f02b8bb8 6831 -- Unchecked_Union, we cannot reference its discriminants
fa1608c2
ES
6832 -- directly. This is why we use the extra parameters of the
6833 -- equality function of the enclosing Unchecked_Union.
5d09245e
AC
6834
6835 -- type UU_Type (Discr : Integer := 0) is
6836 -- . . .
6837 -- end record;
6838 -- pragma Unchecked_Union (UU_Type);
6839
6840 -- 1. Unchecked_Union enclosing record:
6841
6842 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
6843 -- . . .
6844 -- Comp : UU_Type (Discr);
6845 -- . . .
6846 -- end Enclosing_UU_Type;
6847 -- pragma Unchecked_Union (Enclosing_UU_Type);
6848
6849 -- Obj1 : Enclosing_UU_Type;
6850 -- Obj2 : Enclosing_UU_Type (1);
6851
2717634d 6852 -- [. . .] Obj1 = Obj2 [. . .]
5d09245e
AC
6853
6854 -- Generated code:
6855
6856 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
6857
6858 -- A and B are the formal parameters of the equality function
6859 -- of Enclosing_UU_Type. The function always has two extra
fa1608c2
ES
6860 -- formals to capture the inferred discriminant values for
6861 -- each discriminant of the type.
5d09245e
AC
6862
6863 -- 2. Non-Unchecked_Union enclosing record:
6864
6865 -- type
6866 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
6867 -- is record
6868 -- . . .
6869 -- Comp : UU_Type (Discr);
6870 -- . . .
6871 -- end Enclosing_Non_UU_Type;
6872
6873 -- Obj1 : Enclosing_Non_UU_Type;
6874 -- Obj2 : Enclosing_Non_UU_Type (1);
6875
630d30e9 6876 -- ... Obj1 = Obj2 ...
5d09245e
AC
6877
6878 -- Generated code:
6879
6880 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
6881 -- obj1.discr, obj2.discr)) then
6882
6883 -- In this case we can directly reference the discriminants of
6884 -- the enclosing record.
6885
fa1608c2 6886 -- Process left operand of equality
5d09245e
AC
6887
6888 if Nkind (Lhs) = N_Selected_Component
533369aa
AC
6889 and then
6890 Has_Per_Object_Constraint (Entity (Selector_Name (Lhs)))
5d09245e 6891 then
fa1608c2
ES
6892 -- If enclosing record is an Unchecked_Union, use formals
6893 -- corresponding to each discriminant. The name of the
6894 -- formal is that of the discriminant, with added suffix,
6895 -- see Exp_Ch3.Build_Record_Equality for details.
5d09245e 6896
dda38714 6897 if Is_Unchecked_Union (Scope (Entity (Selector_Name (Lhs))))
5d09245e 6898 then
fa1608c2
ES
6899 Discr :=
6900 First_Discriminant
6901 (Scope (Entity (Selector_Name (Lhs))));
6902 while Present (Discr) loop
cc6f5d75
AC
6903 Append_Elmt
6904 (Make_Identifier (Loc,
6905 Chars => New_External_Name (Chars (Discr), 'A')),
6906 To => Lhs_Discr_Vals);
fa1608c2
ES
6907 Next_Discriminant (Discr);
6908 end loop;
5d09245e 6909
fa1608c2
ES
6910 -- If enclosing record is of a non-Unchecked_Union type, it
6911 -- is possible to reference its discriminants directly.
5d09245e
AC
6912
6913 else
fa1608c2
ES
6914 Discr := First_Discriminant (Lhs_Type);
6915 while Present (Discr) loop
cc6f5d75
AC
6916 Append_Elmt
6917 (Make_Selected_Component (Loc,
6918 Prefix => Prefix (Lhs),
6919 Selector_Name =>
6920 New_Copy
6921 (Get_Discriminant_Value (Discr,
6922 Lhs_Type,
6923 Stored_Constraint (Lhs_Type)))),
6924 To => Lhs_Discr_Vals);
fa1608c2
ES
6925 Next_Discriminant (Discr);
6926 end loop;
5d09245e
AC
6927 end if;
6928
fa1608c2
ES
6929 -- Otherwise operand is on object with a constrained type.
6930 -- Infer the discriminant values from the constraint.
5d09245e
AC
6931
6932 else
fa1608c2
ES
6933
6934 Discr := First_Discriminant (Lhs_Type);
6935 while Present (Discr) loop
cc6f5d75
AC
6936 Append_Elmt
6937 (New_Copy
6938 (Get_Discriminant_Value (Discr,
fa1608c2
ES
6939 Lhs_Type,
6940 Stored_Constraint (Lhs_Type))),
cc6f5d75 6941 To => Lhs_Discr_Vals);
fa1608c2
ES
6942 Next_Discriminant (Discr);
6943 end loop;
5d09245e
AC
6944 end if;
6945
fa1608c2 6946 -- Similar processing for right operand of equality
5d09245e
AC
6947
6948 if Nkind (Rhs) = N_Selected_Component
533369aa
AC
6949 and then
6950 Has_Per_Object_Constraint (Entity (Selector_Name (Rhs)))
5d09245e 6951 then
5e1c00fa 6952 if Is_Unchecked_Union
cc6f5d75 6953 (Scope (Entity (Selector_Name (Rhs))))
5d09245e 6954 then
fa1608c2
ES
6955 Discr :=
6956 First_Discriminant
6957 (Scope (Entity (Selector_Name (Rhs))));
6958 while Present (Discr) loop
cc6f5d75
AC
6959 Append_Elmt
6960 (Make_Identifier (Loc,
6961 Chars => New_External_Name (Chars (Discr), 'B')),
6962 To => Rhs_Discr_Vals);
fa1608c2
ES
6963 Next_Discriminant (Discr);
6964 end loop;
5d09245e
AC
6965
6966 else
fa1608c2
ES
6967 Discr := First_Discriminant (Rhs_Type);
6968 while Present (Discr) loop
cc6f5d75
AC
6969 Append_Elmt
6970 (Make_Selected_Component (Loc,
6971 Prefix => Prefix (Rhs),
6972 Selector_Name =>
6973 New_Copy (Get_Discriminant_Value
6974 (Discr,
6975 Rhs_Type,
6976 Stored_Constraint (Rhs_Type)))),
6977 To => Rhs_Discr_Vals);
fa1608c2
ES
6978 Next_Discriminant (Discr);
6979 end loop;
5d09245e 6980 end if;
5d09245e 6981
fa1608c2
ES
6982 else
6983 Discr := First_Discriminant (Rhs_Type);
6984 while Present (Discr) loop
cc6f5d75
AC
6985 Append_Elmt
6986 (New_Copy (Get_Discriminant_Value
6987 (Discr,
6988 Rhs_Type,
6989 Stored_Constraint (Rhs_Type))),
6990 To => Rhs_Discr_Vals);
fa1608c2
ES
6991 Next_Discriminant (Discr);
6992 end loop;
5d09245e
AC
6993 end if;
6994
fa1608c2
ES
6995 -- Now merge the list of discriminant values so that values
6996 -- of corresponding discriminants are adjacent.
6997
6998 declare
6999 Params : List_Id;
7000 L_Elmt : Elmt_Id;
7001 R_Elmt : Elmt_Id;
7002
7003 begin
7004 Params := New_List (L_Exp, R_Exp);
7005 L_Elmt := First_Elmt (Lhs_Discr_Vals);
7006 R_Elmt := First_Elmt (Rhs_Discr_Vals);
7007 while Present (L_Elmt) loop
7008 Append_To (Params, Node (L_Elmt));
7009 Append_To (Params, Node (R_Elmt));
7010 Next_Elmt (L_Elmt);
7011 Next_Elmt (R_Elmt);
7012 end loop;
7013
7014 Rewrite (N,
7015 Make_Function_Call (Loc,
e4494292 7016 Name => New_Occurrence_Of (Eq, Loc),
fa1608c2
ES
7017 Parameter_Associations => Params));
7018 end;
5d09245e
AC
7019 end;
7020
7021 -- Normal case, not an unchecked union
7022
7023 else
7024 Rewrite (N,
7025 Make_Function_Call (Loc,
e4494292 7026 Name => New_Occurrence_Of (Eq, Loc),
5d09245e
AC
7027 Parameter_Associations => New_List (L_Exp, R_Exp)));
7028 end if;
70482933
RK
7029
7030 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
7031 end Build_Equality_Call;
7032
5d09245e
AC
7033 ------------------------------------
7034 -- Has_Unconstrained_UU_Component --
7035 ------------------------------------
7036
7037 function Has_Unconstrained_UU_Component
7038 (Typ : Node_Id) return Boolean
7039 is
7040 Tdef : constant Node_Id :=
57848bf7 7041 Type_Definition (Declaration_Node (Base_Type (Typ)));
5d09245e
AC
7042 Clist : Node_Id;
7043 Vpart : Node_Id;
7044
7045 function Component_Is_Unconstrained_UU
7046 (Comp : Node_Id) return Boolean;
7047 -- Determines whether the subtype of the component is an
7048 -- unconstrained Unchecked_Union.
7049
7050 function Variant_Is_Unconstrained_UU
7051 (Variant : Node_Id) return Boolean;
7052 -- Determines whether a component of the variant has an unconstrained
7053 -- Unchecked_Union subtype.
7054
7055 -----------------------------------
7056 -- Component_Is_Unconstrained_UU --
7057 -----------------------------------
7058
7059 function Component_Is_Unconstrained_UU
7060 (Comp : Node_Id) return Boolean
7061 is
7062 begin
7063 if Nkind (Comp) /= N_Component_Declaration then
7064 return False;
7065 end if;
7066
7067 declare
7068 Sindic : constant Node_Id :=
7069 Subtype_Indication (Component_Definition (Comp));
7070
7071 begin
7072 -- Unconstrained nominal type. In the case of a constraint
7073 -- present, the node kind would have been N_Subtype_Indication.
7074
7075 if Nkind (Sindic) = N_Identifier then
7076 return Is_Unchecked_Union (Base_Type (Etype (Sindic)));
7077 end if;
7078
7079 return False;
7080 end;
7081 end Component_Is_Unconstrained_UU;
7082
7083 ---------------------------------
7084 -- Variant_Is_Unconstrained_UU --
7085 ---------------------------------
7086
7087 function Variant_Is_Unconstrained_UU
7088 (Variant : Node_Id) return Boolean
7089 is
7090 Clist : constant Node_Id := Component_List (Variant);
7091
7092 begin
7093 if Is_Empty_List (Component_Items (Clist)) then
7094 return False;
7095 end if;
7096
f02b8bb8
RD
7097 -- We only need to test one component
7098
5d09245e
AC
7099 declare
7100 Comp : Node_Id := First (Component_Items (Clist));
7101
7102 begin
7103 while Present (Comp) loop
5d09245e
AC
7104 if Component_Is_Unconstrained_UU (Comp) then
7105 return True;
7106 end if;
7107
7108 Next (Comp);
7109 end loop;
7110 end;
7111
7112 -- None of the components withing the variant were of
7113 -- unconstrained Unchecked_Union type.
7114
7115 return False;
7116 end Variant_Is_Unconstrained_UU;
7117
7118 -- Start of processing for Has_Unconstrained_UU_Component
7119
7120 begin
7121 if Null_Present (Tdef) then
7122 return False;
7123 end if;
7124
7125 Clist := Component_List (Tdef);
7126 Vpart := Variant_Part (Clist);
7127
7128 -- Inspect available components
7129
7130 if Present (Component_Items (Clist)) then
7131 declare
7132 Comp : Node_Id := First (Component_Items (Clist));
7133
7134 begin
7135 while Present (Comp) loop
7136
8fc789c8 7137 -- One component is sufficient
5d09245e
AC
7138
7139 if Component_Is_Unconstrained_UU (Comp) then
7140 return True;
7141 end if;
7142
7143 Next (Comp);
7144 end loop;
7145 end;
7146 end if;
7147
7148 -- Inspect available components withing variants
7149
7150 if Present (Vpart) then
7151 declare
7152 Variant : Node_Id := First (Variants (Vpart));
7153
7154 begin
7155 while Present (Variant) loop
7156
8fc789c8 7157 -- One component within a variant is sufficient
5d09245e
AC
7158
7159 if Variant_Is_Unconstrained_UU (Variant) then
7160 return True;
7161 end if;
7162
7163 Next (Variant);
7164 end loop;
7165 end;
7166 end if;
7167
7168 -- Neither the available components, nor the components inside the
7169 -- variant parts were of an unconstrained Unchecked_Union subtype.
7170
7171 return False;
7172 end Has_Unconstrained_UU_Component;
7173
70482933
RK
7174 -- Start of processing for Expand_N_Op_Eq
7175
7176 begin
7177 Binary_Op_Validity_Checks (N);
7178
456cbfa5
AC
7179 -- Deal with private types
7180
70482933
RK
7181 if Ekind (Typl) = E_Private_Type then
7182 Typl := Underlying_Type (Typl);
70482933
RK
7183 elsif Ekind (Typl) = E_Private_Subtype then
7184 Typl := Underlying_Type (Base_Type (Typl));
f02b8bb8
RD
7185 else
7186 null;
70482933
RK
7187 end if;
7188
7189 -- It may happen in error situations that the underlying type is not
7190 -- set. The error will be detected later, here we just defend the
7191 -- expander code.
7192
7193 if No (Typl) then
7194 return;
7195 end if;
7196
a92230c5
AC
7197 -- Now get the implementation base type (note that plain Base_Type here
7198 -- might lead us back to the private type, which is not what we want!)
7199
7200 Typl := Implementation_Base_Type (Typl);
70482933 7201
dda38714
AC
7202 -- Equality between variant records results in a call to a routine
7203 -- that has conditional tests of the discriminant value(s), and hence
7204 -- violates the No_Implicit_Conditionals restriction.
7205
7206 if Has_Variant_Part (Typl) then
7207 declare
7208 Msg : Boolean;
7209
7210 begin
7211 Check_Restriction (Msg, No_Implicit_Conditionals, N);
7212
7213 if Msg then
7214 Error_Msg_N
7215 ("\comparison of variant records tests discriminants", N);
7216 return;
7217 end if;
7218 end;
7219 end if;
7220
456cbfa5 7221 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 7222 -- means we no longer have a comparison operation, we are all done.
456cbfa5
AC
7223
7224 Expand_Compare_Minimize_Eliminate_Overflow (N);
7225
7226 if Nkind (N) /= N_Op_Eq then
7227 return;
7228 end if;
7229
70482933
RK
7230 -- Boolean types (requiring handling of non-standard case)
7231
f02b8bb8 7232 if Is_Boolean_Type (Typl) then
70482933
RK
7233 Adjust_Condition (Left_Opnd (N));
7234 Adjust_Condition (Right_Opnd (N));
7235 Set_Etype (N, Standard_Boolean);
7236 Adjust_Result_Type (N, Typ);
7237
7238 -- Array types
7239
7240 elsif Is_Array_Type (Typl) then
7241
1033834f
RD
7242 -- If we are doing full validity checking, and it is possible for the
7243 -- array elements to be invalid then expand out array comparisons to
7244 -- make sure that we check the array elements.
fbf5a39b 7245
1033834f
RD
7246 if Validity_Check_Operands
7247 and then not Is_Known_Valid (Component_Type (Typl))
7248 then
fbf5a39b
AC
7249 declare
7250 Save_Force_Validity_Checks : constant Boolean :=
7251 Force_Validity_Checks;
7252 begin
7253 Force_Validity_Checks := True;
7254 Rewrite (N,
0da2c8ac
AC
7255 Expand_Array_Equality
7256 (N,
7257 Relocate_Node (Lhs),
7258 Relocate_Node (Rhs),
7259 Bodies,
7260 Typl));
7261 Insert_Actions (N, Bodies);
fbf5a39b
AC
7262 Analyze_And_Resolve (N, Standard_Boolean);
7263 Force_Validity_Checks := Save_Force_Validity_Checks;
7264 end;
7265
a9d8907c 7266 -- Packed case where both operands are known aligned
70482933 7267
a9d8907c
JM
7268 elsif Is_Bit_Packed_Array (Typl)
7269 and then not Is_Possibly_Unaligned_Object (Lhs)
7270 and then not Is_Possibly_Unaligned_Object (Rhs)
7271 then
70482933
RK
7272 Expand_Packed_Eq (N);
7273
5e1c00fa
RD
7274 -- Where the component type is elementary we can use a block bit
7275 -- comparison (if supported on the target) exception in the case
7276 -- of floating-point (negative zero issues require element by
7277 -- element comparison), and atomic types (where we must be sure
a9d8907c 7278 -- to load elements independently) and possibly unaligned arrays.
70482933 7279
70482933
RK
7280 elsif Is_Elementary_Type (Component_Type (Typl))
7281 and then not Is_Floating_Point_Type (Component_Type (Typl))
5e1c00fa 7282 and then not Is_Atomic (Component_Type (Typl))
a9d8907c
JM
7283 and then not Is_Possibly_Unaligned_Object (Lhs)
7284 and then not Is_Possibly_Unaligned_Object (Rhs)
fbf5a39b 7285 and then Support_Composite_Compare_On_Target
70482933
RK
7286 then
7287 null;
7288
685094bf
RD
7289 -- For composite and floating-point cases, expand equality loop to
7290 -- make sure of using proper comparisons for tagged types, and
7291 -- correctly handling the floating-point case.
70482933
RK
7292
7293 else
7294 Rewrite (N,
0da2c8ac
AC
7295 Expand_Array_Equality
7296 (N,
7297 Relocate_Node (Lhs),
7298 Relocate_Node (Rhs),
7299 Bodies,
7300 Typl));
70482933
RK
7301 Insert_Actions (N, Bodies, Suppress => All_Checks);
7302 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
7303 end if;
7304
7305 -- Record Types
7306
7307 elsif Is_Record_Type (Typl) then
7308
7309 -- For tagged types, use the primitive "="
7310
7311 if Is_Tagged_Type (Typl) then
7312
0669bebe
GB
7313 -- No need to do anything else compiling under restriction
7314 -- No_Dispatching_Calls. During the semantic analysis we
7315 -- already notified such violation.
7316
7317 if Restriction_Active (No_Dispatching_Calls) then
7318 return;
7319 end if;
7320
685094bf
RD
7321 -- If this is derived from an untagged private type completed with
7322 -- a tagged type, it does not have a full view, so we use the
7323 -- primitive operations of the private type. This check should no
7324 -- longer be necessary when these types get their full views???
70482933
RK
7325
7326 if Is_Private_Type (A_Typ)
7327 and then not Is_Tagged_Type (A_Typ)
7328 and then Is_Derived_Type (A_Typ)
7329 and then No (Full_View (A_Typ))
7330 then
685094bf
RD
7331 -- Search for equality operation, checking that the operands
7332 -- have the same type. Note that we must find a matching entry,
a90bd866 7333 -- or something is very wrong.
2e071734 7334
70482933
RK
7335 Prim := First_Elmt (Collect_Primitive_Operations (A_Typ));
7336
2e071734
AC
7337 while Present (Prim) loop
7338 exit when Chars (Node (Prim)) = Name_Op_Eq
7339 and then Etype (First_Formal (Node (Prim))) =
7340 Etype (Next_Formal (First_Formal (Node (Prim))))
7341 and then
7342 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
7343
70482933 7344 Next_Elmt (Prim);
70482933
RK
7345 end loop;
7346
2e071734 7347 pragma Assert (Present (Prim));
70482933 7348 Op_Name := Node (Prim);
fbf5a39b
AC
7349
7350 -- Find the type's predefined equality or an overriding
3dddb11e 7351 -- user-defined equality. The reason for not simply calling
fbf5a39b 7352 -- Find_Prim_Op here is that there may be a user-defined
3dddb11e
ES
7353 -- overloaded equality op that precedes the equality that we
7354 -- want, so we have to explicitly search (e.g., there could be
7355 -- an equality with two different parameter types).
fbf5a39b 7356
70482933 7357 else
fbf5a39b 7358 if Is_Class_Wide_Type (Typl) then
3dddb11e 7359 Typl := Find_Specific_Type (Typl);
fbf5a39b
AC
7360 end if;
7361
7362 Prim := First_Elmt (Primitive_Operations (Typl));
fbf5a39b
AC
7363 while Present (Prim) loop
7364 exit when Chars (Node (Prim)) = Name_Op_Eq
7365 and then Etype (First_Formal (Node (Prim))) =
7366 Etype (Next_Formal (First_Formal (Node (Prim))))
12e0c41c
AC
7367 and then
7368 Base_Type (Etype (Node (Prim))) = Standard_Boolean;
fbf5a39b
AC
7369
7370 Next_Elmt (Prim);
fbf5a39b
AC
7371 end loop;
7372
2e071734 7373 pragma Assert (Present (Prim));
fbf5a39b 7374 Op_Name := Node (Prim);
70482933
RK
7375 end if;
7376
7377 Build_Equality_Call (Op_Name);
7378
5d09245e
AC
7379 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
7380 -- predefined equality operator for a type which has a subcomponent
7381 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
7382
7383 elsif Has_Unconstrained_UU_Component (Typl) then
7384 Insert_Action (N,
7385 Make_Raise_Program_Error (Loc,
7386 Reason => PE_Unchecked_Union_Restriction));
7387
7388 -- Prevent Gigi from generating incorrect code by rewriting the
6cb3037c 7389 -- equality as a standard False. (is this documented somewhere???)
5d09245e
AC
7390
7391 Rewrite (N,
7392 New_Occurrence_Of (Standard_False, Loc));
7393
7394 elsif Is_Unchecked_Union (Typl) then
7395
7396 -- If we can infer the discriminants of the operands, we make a
7397 -- call to the TSS equality function.
7398
7399 if Has_Inferable_Discriminants (Lhs)
7400 and then
7401 Has_Inferable_Discriminants (Rhs)
7402 then
7403 Build_Equality_Call
7404 (TSS (Root_Type (Typl), TSS_Composite_Equality));
7405
7406 else
7407 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
7408 -- the predefined equality operator for an Unchecked_Union type
7409 -- if either of the operands lack inferable discriminants.
7410
7411 Insert_Action (N,
7412 Make_Raise_Program_Error (Loc,
7413 Reason => PE_Unchecked_Union_Restriction));
7414
29ad9ea5
AC
7415 -- Emit a warning on source equalities only, otherwise the
7416 -- message may appear out of place due to internal use. The
7417 -- warning is unconditional because it is required by the
7418 -- language.
7419
7420 if Comes_From_Source (N) then
7421 Error_Msg_N
facfa165 7422 ("Unchecked_Union discriminants cannot be determined??",
29ad9ea5
AC
7423 N);
7424 Error_Msg_N
facfa165 7425 ("\Program_Error will be raised for equality operation??",
29ad9ea5
AC
7426 N);
7427 end if;
7428
5d09245e 7429 -- Prevent Gigi from generating incorrect code by rewriting
6cb3037c 7430 -- the equality as a standard False (documented where???).
5d09245e
AC
7431
7432 Rewrite (N,
7433 New_Occurrence_Of (Standard_False, Loc));
5d09245e
AC
7434 end if;
7435
70482933
RK
7436 -- If a type support function is present (for complex cases), use it
7437
fbf5a39b
AC
7438 elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
7439 Build_Equality_Call
7440 (TSS (Root_Type (Typl), TSS_Composite_Equality));
70482933 7441
8d80ff64
AC
7442 -- When comparing two Bounded_Strings, use the primitive equality of
7443 -- the root Super_String type.
7444
7445 elsif Is_Bounded_String (Typl) then
7446 Prim :=
7447 First_Elmt (Collect_Primitive_Operations (Root_Type (Typl)));
7448
7449 while Present (Prim) loop
7450 exit when Chars (Node (Prim)) = Name_Op_Eq
7451 and then Etype (First_Formal (Node (Prim))) =
7452 Etype (Next_Formal (First_Formal (Node (Prim))))
7453 and then Base_Type (Etype (Node (Prim))) = Standard_Boolean;
7454
7455 Next_Elmt (Prim);
7456 end loop;
7457
7458 -- A Super_String type should always have a primitive equality
7459
7460 pragma Assert (Present (Prim));
7461 Build_Equality_Call (Node (Prim));
7462
70482933 7463 -- Otherwise expand the component by component equality. Note that
8fc789c8 7464 -- we never use block-bit comparisons for records, because of the
70482933
RK
7465 -- problems with gaps. The backend will often be able to recombine
7466 -- the separate comparisons that we generate here.
7467
7468 else
7469 Remove_Side_Effects (Lhs);
7470 Remove_Side_Effects (Rhs);
7471 Rewrite (N,
7472 Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
7473
7474 Insert_Actions (N, Bodies, Suppress => All_Checks);
7475 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
7476 end if;
7477 end if;
7478
d26dc4b5 7479 -- Test if result is known at compile time
70482933 7480
d26dc4b5 7481 Rewrite_Comparison (N);
f02b8bb8 7482
0580d807 7483 Optimize_Length_Comparison (N);
70482933
RK
7484 end Expand_N_Op_Eq;
7485
7486 -----------------------
7487 -- Expand_N_Op_Expon --
7488 -----------------------
7489
7490 procedure Expand_N_Op_Expon (N : Node_Id) is
7491 Loc : constant Source_Ptr := Sloc (N);
7492 Typ : constant Entity_Id := Etype (N);
7493 Rtyp : constant Entity_Id := Root_Type (Typ);
7494 Base : constant Node_Id := Relocate_Node (Left_Opnd (N));
07fc65c4 7495 Bastyp : constant Node_Id := Etype (Base);
70482933
RK
7496 Exp : constant Node_Id := Relocate_Node (Right_Opnd (N));
7497 Exptyp : constant Entity_Id := Etype (Exp);
7498 Ovflo : constant Boolean := Do_Overflow_Check (N);
7499 Expv : Uint;
70482933
RK
7500 Temp : Node_Id;
7501 Rent : RE_Id;
7502 Ent : Entity_Id;
fbf5a39b 7503 Etyp : Entity_Id;
cb42ba5d 7504 Xnode : Node_Id;
70482933
RK
7505
7506 begin
7507 Binary_Op_Validity_Checks (N);
7508
5114f3ff 7509 -- CodePeer wants to see the unexpanded N_Op_Expon node
8f66cda7 7510
5114f3ff 7511 if CodePeer_Mode then
8f66cda7
AC
7512 return;
7513 end if;
7514
685094bf
RD
7515 -- If either operand is of a private type, then we have the use of an
7516 -- intrinsic operator, and we get rid of the privateness, by using root
7517 -- types of underlying types for the actual operation. Otherwise the
7518 -- private types will cause trouble if we expand multiplications or
7519 -- shifts etc. We also do this transformation if the result type is
7520 -- different from the base type.
07fc65c4
GB
7521
7522 if Is_Private_Type (Etype (Base))
8f66cda7
AC
7523 or else Is_Private_Type (Typ)
7524 or else Is_Private_Type (Exptyp)
7525 or else Rtyp /= Root_Type (Bastyp)
07fc65c4
GB
7526 then
7527 declare
7528 Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
7529 Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
07fc65c4
GB
7530 begin
7531 Rewrite (N,
7532 Unchecked_Convert_To (Typ,
7533 Make_Op_Expon (Loc,
7534 Left_Opnd => Unchecked_Convert_To (Bt, Base),
7535 Right_Opnd => Unchecked_Convert_To (Et, Exp))));
7536 Analyze_And_Resolve (N, Typ);
7537 return;
7538 end;
7539 end if;
7540
b6b5cca8 7541 -- Check for MINIMIZED/ELIMINATED overflow mode
6cb3037c 7542
b6b5cca8 7543 if Minimized_Eliminated_Overflow_Check (N) then
6cb3037c
AC
7544 Apply_Arithmetic_Overflow_Check (N);
7545 return;
7546 end if;
7547
cb42ba5d
AC
7548 -- Test for case of known right argument where we can replace the
7549 -- exponentiation by an equivalent expression using multiplication.
70482933 7550
6c3c671e
AC
7551 -- Note: use CRT_Safe version of Compile_Time_Known_Value because in
7552 -- configurable run-time mode, we may not have the exponentiation
7553 -- routine available, and we don't want the legality of the program
7554 -- to depend on how clever the compiler is in knowing values.
7555
7556 if CRT_Safe_Compile_Time_Known_Value (Exp) then
70482933
RK
7557 Expv := Expr_Value (Exp);
7558
7559 -- We only fold small non-negative exponents. You might think we
7560 -- could fold small negative exponents for the real case, but we
7561 -- can't because we are required to raise Constraint_Error for
7562 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
7563 -- See ACVC test C4A012B.
7564
7565 if Expv >= 0 and then Expv <= 4 then
7566
7567 -- X ** 0 = 1 (or 1.0)
7568
7569 if Expv = 0 then
abcbd24c
ST
7570
7571 -- Call Remove_Side_Effects to ensure that any side effects
7572 -- in the ignored left operand (in particular function calls
7573 -- to user defined functions) are properly executed.
7574
7575 Remove_Side_Effects (Base);
7576
70482933
RK
7577 if Ekind (Typ) in Integer_Kind then
7578 Xnode := Make_Integer_Literal (Loc, Intval => 1);
7579 else
7580 Xnode := Make_Real_Literal (Loc, Ureal_1);
7581 end if;
7582
7583 -- X ** 1 = X
7584
7585 elsif Expv = 1 then
7586 Xnode := Base;
7587
7588 -- X ** 2 = X * X
7589
7590 elsif Expv = 2 then
7591 Xnode :=
7592 Make_Op_Multiply (Loc,
7593 Left_Opnd => Duplicate_Subexpr (Base),
fbf5a39b 7594 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
70482933
RK
7595
7596 -- X ** 3 = X * X * X
7597
7598 elsif Expv = 3 then
7599 Xnode :=
7600 Make_Op_Multiply (Loc,
7601 Left_Opnd =>
7602 Make_Op_Multiply (Loc,
7603 Left_Opnd => Duplicate_Subexpr (Base),
fbf5a39b
AC
7604 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
7605 Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
70482933
RK
7606
7607 -- X ** 4 ->
cb42ba5d
AC
7608
7609 -- do
70482933 7610 -- En : constant base'type := base * base;
cb42ba5d 7611 -- in
70482933
RK
7612 -- En * En
7613
cb42ba5d
AC
7614 else
7615 pragma Assert (Expv = 4);
191fcb3a 7616 Temp := Make_Temporary (Loc, 'E', Base);
70482933 7617
cb42ba5d
AC
7618 Xnode :=
7619 Make_Expression_With_Actions (Loc,
7620 Actions => New_List (
7621 Make_Object_Declaration (Loc,
7622 Defining_Identifier => Temp,
7623 Constant_Present => True,
e4494292 7624 Object_Definition => New_Occurrence_Of (Typ, Loc),
cb42ba5d
AC
7625 Expression =>
7626 Make_Op_Multiply (Loc,
7627 Left_Opnd =>
7628 Duplicate_Subexpr (Base),
7629 Right_Opnd =>
7630 Duplicate_Subexpr_No_Checks (Base)))),
7631
70482933
RK
7632 Expression =>
7633 Make_Op_Multiply (Loc,
e4494292
RD
7634 Left_Opnd => New_Occurrence_Of (Temp, Loc),
7635 Right_Opnd => New_Occurrence_Of (Temp, Loc)));
70482933
RK
7636 end if;
7637
7638 Rewrite (N, Xnode);
7639 Analyze_And_Resolve (N, Typ);
7640 return;
7641 end if;
7642 end if;
7643
b502ba3c 7644 -- Deal with optimizing 2 ** expression to shift where possible
685094bf 7645
8b4230c8
AC
7646 -- Note: we used to check that Exptyp was an unsigned type. But that is
7647 -- an unnecessary check, since if Exp is negative, we have a run-time
7648 -- error that is either caught (so we get the right result) or we have
7649 -- suppressed the check, in which case the code is erroneous anyway.
7650
b502ba3c
RD
7651 if Is_Integer_Type (Rtyp)
7652
c2b2b2d7 7653 -- The base value must be "safe compile-time known", and exactly 2
b502ba3c
RD
7654
7655 and then Nkind (Base) = N_Integer_Literal
6c3c671e
AC
7656 and then CRT_Safe_Compile_Time_Known_Value (Base)
7657 and then Expr_Value (Base) = Uint_2
b502ba3c
RD
7658
7659 -- We only handle cases where the right type is a integer
7660
70482933
RK
7661 and then Is_Integer_Type (Root_Type (Exptyp))
7662 and then Esize (Root_Type (Exptyp)) <= Esize (Standard_Integer)
b502ba3c
RD
7663
7664 -- This transformation is not applicable for a modular type with a
a95f708e 7665 -- nonbinary modulus because we do not handle modular reduction in
b502ba3c
RD
7666 -- a correct manner if we attempt this transformation in this case.
7667
7668 and then not Non_Binary_Modulus (Typ)
70482933 7669 then
b502ba3c
RD
7670 -- Handle the cases where our parent is a division or multiplication
7671 -- specially. In these cases we can convert to using a shift at the
7672 -- parent level if we are not doing overflow checking, since it is
7673 -- too tricky to combine the overflow check at the parent level.
70482933 7674
b502ba3c
RD
7675 if not Ovflo
7676 and then Nkind_In (Parent (N), N_Op_Divide, N_Op_Multiply)
7677 then
51bf9bdf
AC
7678 declare
7679 P : constant Node_Id := Parent (N);
7680 L : constant Node_Id := Left_Opnd (P);
7681 R : constant Node_Id := Right_Opnd (P);
7682
7683 begin
7684 if (Nkind (P) = N_Op_Multiply
eb9008b7
AC
7685 and then
7686 ((Is_Integer_Type (Etype (L)) and then R = N)
7687 or else
7688 (Is_Integer_Type (Etype (R)) and then L = N))
7689 and then not Do_Overflow_Check (P))
7690
51bf9bdf
AC
7691 or else
7692 (Nkind (P) = N_Op_Divide
533369aa
AC
7693 and then Is_Integer_Type (Etype (L))
7694 and then Is_Unsigned_Type (Etype (L))
7695 and then R = N
7696 and then not Do_Overflow_Check (P))
51bf9bdf
AC
7697 then
7698 Set_Is_Power_Of_2_For_Shift (N);
7699 return;
7700 end if;
7701 end;
7702
b502ba3c
RD
7703 -- Here we just have 2 ** N on its own, so we can convert this to a
7704 -- shift node. We are prepared to deal with overflow here, and we
7705 -- also have to handle proper modular reduction for binary modular.
51bf9bdf 7706
b502ba3c
RD
7707 else
7708 declare
7709 OK : Boolean;
7710 Lo : Uint;
7711 Hi : Uint;
7712
7713 MaxS : Uint;
7714 -- Maximum shift count with no overflow
7715
7716 TestS : Boolean;
7717 -- Set True if we must test the shift count
7718
7719 begin
7720 -- Compute maximum shift based on the underlying size. For a
7721 -- modular type this is one less than the size.
7722
7723 if Is_Modular_Integer_Type (Typ) then
7724
7725 -- For modular integer types, this is the size of the value
7726 -- being shifted minus one. Any larger values will cause
7727 -- modular reduction to a result of zero. Note that we do
7728 -- want the RM_Size here (e.g. mod 2 ** 7, we want a result
7729 -- of 6, since 2**7 should be reduced to zero).
7730
7731 MaxS := RM_Size (Rtyp) - 1;
7732
7733 -- For signed integer types, we use the size of the value
7734 -- being shifted minus 2. Larger values cause overflow.
7735
7736 else
7737 MaxS := Esize (Rtyp) - 2;
7738 end if;
7739
7740 -- Determine range to see if it can be larger than MaxS
7741
7742 Determine_Range
7743 (Right_Opnd (N), OK, Lo, Hi, Assume_Valid => True);
7744 TestS := (not OK) or else Hi > MaxS;
7745
7746 -- Signed integer case
7747
7748 if Is_Signed_Integer_Type (Typ) then
7749
7750 -- Generate overflow check if overflow is active. Note that
7751 -- we can simply ignore the possibility of overflow if the
7752 -- flag is not set (means that overflow cannot happen or
7753 -- that overflow checks are suppressed).
7754
7755 if Ovflo and TestS then
7756 Insert_Action (N,
7757 Make_Raise_Constraint_Error (Loc,
7758 Condition =>
7759 Make_Op_Gt (Loc,
7760 Left_Opnd => Duplicate_Subexpr (Right_Opnd (N)),
7761 Right_Opnd => Make_Integer_Literal (Loc, MaxS)),
7762 Reason => CE_Overflow_Check_Failed));
7763 end if;
7764
7765 -- Now rewrite node as Shift_Left (1, right-operand)
7766
7767 Rewrite (N,
7768 Make_Op_Shift_Left (Loc,
7769 Left_Opnd => Make_Integer_Literal (Loc, Uint_1),
7770 Right_Opnd => Right_Opnd (N)));
7771
7772 -- Modular integer case
7773
7774 else pragma Assert (Is_Modular_Integer_Type (Typ));
7775
7776 -- If shift count can be greater than MaxS, we need to wrap
7777 -- the shift in a test that will reduce the result value to
7778 -- zero if this shift count is exceeded.
7779
7780 if TestS then
7781 Rewrite (N,
7782 Make_If_Expression (Loc,
7783 Expressions => New_List (
7784 Make_Op_Gt (Loc,
7785 Left_Opnd => Duplicate_Subexpr (Right_Opnd (N)),
7786 Right_Opnd => Make_Integer_Literal (Loc, MaxS)),
7787
7788 Make_Integer_Literal (Loc, Uint_0),
7789
7790 Make_Op_Shift_Left (Loc,
7791 Left_Opnd => Make_Integer_Literal (Loc, Uint_1),
7792 Right_Opnd => Right_Opnd (N)))));
7793
7794 -- If we know shift count cannot be greater than MaxS, then
7795 -- it is safe to just rewrite as a shift with no test.
7796
7797 else
7798 Rewrite (N,
7799 Make_Op_Shift_Left (Loc,
7800 Left_Opnd => Make_Integer_Literal (Loc, Uint_1),
7801 Right_Opnd => Right_Opnd (N)));
7802 end if;
7803 end if;
7804
7805 Analyze_And_Resolve (N, Typ);
7806 return;
7807 end;
51bf9bdf 7808 end if;
70482933
RK
7809 end if;
7810
07fc65c4
GB
7811 -- Fall through if exponentiation must be done using a runtime routine
7812
07fc65c4 7813 -- First deal with modular case
70482933
RK
7814
7815 if Is_Modular_Integer_Type (Rtyp) then
7816
a95f708e
RD
7817 -- Nonbinary case, we call the special exponentiation routine for
7818 -- the nonbinary case, converting the argument to Long_Long_Integer
70482933
RK
7819 -- and passing the modulus value. Then the result is converted back
7820 -- to the base type.
7821
7822 if Non_Binary_Modulus (Rtyp) then
70482933
RK
7823 Rewrite (N,
7824 Convert_To (Typ,
7825 Make_Function_Call (Loc,
cc6f5d75
AC
7826 Name =>
7827 New_Occurrence_Of (RTE (RE_Exp_Modular), Loc),
70482933 7828 Parameter_Associations => New_List (
e9daba51 7829 Convert_To (RTE (RE_Unsigned), Base),
70482933
RK
7830 Make_Integer_Literal (Loc, Modulus (Rtyp)),
7831 Exp))));
7832
685094bf
RD
7833 -- Binary case, in this case, we call one of two routines, either the
7834 -- unsigned integer case, or the unsigned long long integer case,
7835 -- with a final "and" operation to do the required mod.
70482933
RK
7836
7837 else
7838 if UI_To_Int (Esize (Rtyp)) <= Standard_Integer_Size then
7839 Ent := RTE (RE_Exp_Unsigned);
7840 else
7841 Ent := RTE (RE_Exp_Long_Long_Unsigned);
7842 end if;
7843
7844 Rewrite (N,
7845 Convert_To (Typ,
7846 Make_Op_And (Loc,
cc6f5d75 7847 Left_Opnd =>
70482933 7848 Make_Function_Call (Loc,
cc6f5d75 7849 Name => New_Occurrence_Of (Ent, Loc),
70482933
RK
7850 Parameter_Associations => New_List (
7851 Convert_To (Etype (First_Formal (Ent)), Base),
7852 Exp)),
7853 Right_Opnd =>
7854 Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
7855
7856 end if;
7857
7858 -- Common exit point for modular type case
7859
7860 Analyze_And_Resolve (N, Typ);
7861 return;
7862
fbf5a39b
AC
7863 -- Signed integer cases, done using either Integer or Long_Long_Integer.
7864 -- It is not worth having routines for Short_[Short_]Integer, since for
7865 -- most machines it would not help, and it would generate more code that
dfd99a80 7866 -- might need certification when a certified run time is required.
70482933 7867
fbf5a39b 7868 -- In the integer cases, we have two routines, one for when overflow
dfd99a80
TQ
7869 -- checks are required, and one when they are not required, since there
7870 -- is a real gain in omitting checks on many machines.
70482933 7871
fbf5a39b
AC
7872 elsif Rtyp = Base_Type (Standard_Long_Long_Integer)
7873 or else (Rtyp = Base_Type (Standard_Long_Integer)
761f7dcb
AC
7874 and then
7875 Esize (Standard_Long_Integer) > Esize (Standard_Integer))
7876 or else Rtyp = Universal_Integer
70482933 7877 then
fbf5a39b
AC
7878 Etyp := Standard_Long_Long_Integer;
7879
ebb6b0bd
AC
7880 -- Overflow checking is the only choice on the AAMP target, where
7881 -- arithmetic instructions check overflow automatically, so only
7882 -- one version of the exponentiation unit is needed.
7883
1037b0f4 7884 if Ovflo or AAMP_On_Target then
70482933
RK
7885 Rent := RE_Exp_Long_Long_Integer;
7886 else
7887 Rent := RE_Exn_Long_Long_Integer;
7888 end if;
7889
fbf5a39b
AC
7890 elsif Is_Signed_Integer_Type (Rtyp) then
7891 Etyp := Standard_Integer;
70482933 7892
ebb6b0bd
AC
7893 -- Overflow checking is the only choice on the AAMP target, where
7894 -- arithmetic instructions check overflow automatically, so only
7895 -- one version of the exponentiation unit is needed.
7896
1037b0f4 7897 if Ovflo or AAMP_On_Target then
fbf5a39b 7898 Rent := RE_Exp_Integer;
70482933 7899 else
fbf5a39b 7900 Rent := RE_Exn_Integer;
70482933 7901 end if;
fbf5a39b
AC
7902
7903 -- Floating-point cases, always done using Long_Long_Float. We do not
7904 -- need separate routines for the overflow case here, since in the case
7905 -- of floating-point, we generate infinities anyway as a rule (either
7906 -- that or we automatically trap overflow), and if there is an infinity
7907 -- generated and a range check is required, the check will fail anyway.
7908
7909 else
7910 pragma Assert (Is_Floating_Point_Type (Rtyp));
7911 Etyp := Standard_Long_Long_Float;
7912 Rent := RE_Exn_Long_Long_Float;
70482933
RK
7913 end if;
7914
7915 -- Common processing for integer cases and floating-point cases.
fbf5a39b 7916 -- If we are in the right type, we can call runtime routine directly
70482933 7917
fbf5a39b 7918 if Typ = Etyp
70482933
RK
7919 and then Rtyp /= Universal_Integer
7920 and then Rtyp /= Universal_Real
7921 then
7922 Rewrite (N,
7923 Make_Function_Call (Loc,
e4494292 7924 Name => New_Occurrence_Of (RTE (Rent), Loc),
70482933
RK
7925 Parameter_Associations => New_List (Base, Exp)));
7926
7927 -- Otherwise we have to introduce conversions (conversions are also
fbf5a39b 7928 -- required in the universal cases, since the runtime routine is
1147c704 7929 -- typed using one of the standard types).
70482933
RK
7930
7931 else
7932 Rewrite (N,
7933 Convert_To (Typ,
7934 Make_Function_Call (Loc,
e4494292 7935 Name => New_Occurrence_Of (RTE (Rent), Loc),
70482933 7936 Parameter_Associations => New_List (
fbf5a39b 7937 Convert_To (Etyp, Base),
70482933
RK
7938 Exp))));
7939 end if;
7940
7941 Analyze_And_Resolve (N, Typ);
7942 return;
7943
fbf5a39b
AC
7944 exception
7945 when RE_Not_Available =>
7946 return;
70482933
RK
7947 end Expand_N_Op_Expon;
7948
7949 --------------------
7950 -- Expand_N_Op_Ge --
7951 --------------------
7952
7953 procedure Expand_N_Op_Ge (N : Node_Id) is
7954 Typ : constant Entity_Id := Etype (N);
7955 Op1 : constant Node_Id := Left_Opnd (N);
7956 Op2 : constant Node_Id := Right_Opnd (N);
7957 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
7958
7959 begin
7960 Binary_Op_Validity_Checks (N);
7961
456cbfa5 7962 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 7963 -- means we no longer have a comparison operation, we are all done.
456cbfa5
AC
7964
7965 Expand_Compare_Minimize_Eliminate_Overflow (N);
7966
7967 if Nkind (N) /= N_Op_Ge then
7968 return;
7969 end if;
7970
7971 -- Array type case
7972
f02b8bb8 7973 if Is_Array_Type (Typ1) then
70482933
RK
7974 Expand_Array_Comparison (N);
7975 return;
7976 end if;
7977
456cbfa5
AC
7978 -- Deal with boolean operands
7979
70482933
RK
7980 if Is_Boolean_Type (Typ1) then
7981 Adjust_Condition (Op1);
7982 Adjust_Condition (Op2);
7983 Set_Etype (N, Standard_Boolean);
7984 Adjust_Result_Type (N, Typ);
7985 end if;
7986
7987 Rewrite_Comparison (N);
f02b8bb8 7988
0580d807 7989 Optimize_Length_Comparison (N);
70482933
RK
7990 end Expand_N_Op_Ge;
7991
7992 --------------------
7993 -- Expand_N_Op_Gt --
7994 --------------------
7995
7996 procedure Expand_N_Op_Gt (N : Node_Id) is
7997 Typ : constant Entity_Id := Etype (N);
7998 Op1 : constant Node_Id := Left_Opnd (N);
7999 Op2 : constant Node_Id := Right_Opnd (N);
8000 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
8001
8002 begin
8003 Binary_Op_Validity_Checks (N);
8004
456cbfa5 8005 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 8006 -- means we no longer have a comparison operation, we are all done.
456cbfa5
AC
8007
8008 Expand_Compare_Minimize_Eliminate_Overflow (N);
8009
8010 if Nkind (N) /= N_Op_Gt then
8011 return;
8012 end if;
8013
8014 -- Deal with array type operands
8015
f02b8bb8 8016 if Is_Array_Type (Typ1) then
70482933
RK
8017 Expand_Array_Comparison (N);
8018 return;
8019 end if;
8020
456cbfa5
AC
8021 -- Deal with boolean type operands
8022
70482933
RK
8023 if Is_Boolean_Type (Typ1) then
8024 Adjust_Condition (Op1);
8025 Adjust_Condition (Op2);
8026 Set_Etype (N, Standard_Boolean);
8027 Adjust_Result_Type (N, Typ);
8028 end if;
8029
8030 Rewrite_Comparison (N);
f02b8bb8 8031
0580d807 8032 Optimize_Length_Comparison (N);
70482933
RK
8033 end Expand_N_Op_Gt;
8034
8035 --------------------
8036 -- Expand_N_Op_Le --
8037 --------------------
8038
8039 procedure Expand_N_Op_Le (N : Node_Id) is
8040 Typ : constant Entity_Id := Etype (N);
8041 Op1 : constant Node_Id := Left_Opnd (N);
8042 Op2 : constant Node_Id := Right_Opnd (N);
8043 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
8044
8045 begin
8046 Binary_Op_Validity_Checks (N);
8047
456cbfa5 8048 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 8049 -- means we no longer have a comparison operation, we are all done.
456cbfa5
AC
8050
8051 Expand_Compare_Minimize_Eliminate_Overflow (N);
8052
8053 if Nkind (N) /= N_Op_Le then
8054 return;
8055 end if;
8056
8057 -- Deal with array type operands
8058
f02b8bb8 8059 if Is_Array_Type (Typ1) then
70482933
RK
8060 Expand_Array_Comparison (N);
8061 return;
8062 end if;
8063
456cbfa5
AC
8064 -- Deal with Boolean type operands
8065
70482933
RK
8066 if Is_Boolean_Type (Typ1) then
8067 Adjust_Condition (Op1);
8068 Adjust_Condition (Op2);
8069 Set_Etype (N, Standard_Boolean);
8070 Adjust_Result_Type (N, Typ);
8071 end if;
8072
8073 Rewrite_Comparison (N);
f02b8bb8 8074
0580d807 8075 Optimize_Length_Comparison (N);
70482933
RK
8076 end Expand_N_Op_Le;
8077
8078 --------------------
8079 -- Expand_N_Op_Lt --
8080 --------------------
8081
8082 procedure Expand_N_Op_Lt (N : Node_Id) is
8083 Typ : constant Entity_Id := Etype (N);
8084 Op1 : constant Node_Id := Left_Opnd (N);
8085 Op2 : constant Node_Id := Right_Opnd (N);
8086 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
8087
8088 begin
8089 Binary_Op_Validity_Checks (N);
8090
456cbfa5 8091 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 8092 -- means we no longer have a comparison operation, we are all done.
456cbfa5
AC
8093
8094 Expand_Compare_Minimize_Eliminate_Overflow (N);
8095
8096 if Nkind (N) /= N_Op_Lt then
8097 return;
8098 end if;
8099
8100 -- Deal with array type operands
8101
f02b8bb8 8102 if Is_Array_Type (Typ1) then
70482933
RK
8103 Expand_Array_Comparison (N);
8104 return;
8105 end if;
8106
456cbfa5
AC
8107 -- Deal with Boolean type operands
8108
70482933
RK
8109 if Is_Boolean_Type (Typ1) then
8110 Adjust_Condition (Op1);
8111 Adjust_Condition (Op2);
8112 Set_Etype (N, Standard_Boolean);
8113 Adjust_Result_Type (N, Typ);
8114 end if;
8115
8116 Rewrite_Comparison (N);
f02b8bb8 8117
0580d807 8118 Optimize_Length_Comparison (N);
70482933
RK
8119 end Expand_N_Op_Lt;
8120
8121 -----------------------
8122 -- Expand_N_Op_Minus --
8123 -----------------------
8124
8125 procedure Expand_N_Op_Minus (N : Node_Id) is
8126 Loc : constant Source_Ptr := Sloc (N);
8127 Typ : constant Entity_Id := Etype (N);
8128
8129 begin
8130 Unary_Op_Validity_Checks (N);
8131
b6b5cca8
AC
8132 -- Check for MINIMIZED/ELIMINATED overflow mode
8133
8134 if Minimized_Eliminated_Overflow_Check (N) then
8135 Apply_Arithmetic_Overflow_Check (N);
8136 return;
8137 end if;
8138
07fc65c4 8139 if not Backend_Overflow_Checks_On_Target
70482933
RK
8140 and then Is_Signed_Integer_Type (Etype (N))
8141 and then Do_Overflow_Check (N)
8142 then
8143 -- Software overflow checking expands -expr into (0 - expr)
8144
8145 Rewrite (N,
8146 Make_Op_Subtract (Loc,
8147 Left_Opnd => Make_Integer_Literal (Loc, 0),
8148 Right_Opnd => Right_Opnd (N)));
8149
8150 Analyze_And_Resolve (N, Typ);
70482933
RK
8151 end if;
8152 end Expand_N_Op_Minus;
8153
8154 ---------------------
8155 -- Expand_N_Op_Mod --
8156 ---------------------
8157
8158 procedure Expand_N_Op_Mod (N : Node_Id) is
8159 Loc : constant Source_Ptr := Sloc (N);
fbf5a39b 8160 Typ : constant Entity_Id := Etype (N);
70482933
RK
8161 DDC : constant Boolean := Do_Division_Check (N);
8162
b6b5cca8
AC
8163 Left : Node_Id;
8164 Right : Node_Id;
8165
70482933
RK
8166 LLB : Uint;
8167 Llo : Uint;
8168 Lhi : Uint;
8169 LOK : Boolean;
8170 Rlo : Uint;
8171 Rhi : Uint;
8172 ROK : Boolean;
8173
1033834f
RD
8174 pragma Warnings (Off, Lhi);
8175
70482933
RK
8176 begin
8177 Binary_Op_Validity_Checks (N);
8178
b6b5cca8
AC
8179 -- Check for MINIMIZED/ELIMINATED overflow mode
8180
8181 if Minimized_Eliminated_Overflow_Check (N) then
8182 Apply_Arithmetic_Overflow_Check (N);
8183 return;
8184 end if;
8185
9a6dc470
RD
8186 if Is_Integer_Type (Etype (N)) then
8187 Apply_Divide_Checks (N);
b6b5cca8
AC
8188
8189 -- All done if we don't have a MOD any more, which can happen as a
8190 -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
8191
8192 if Nkind (N) /= N_Op_Mod then
8193 return;
8194 end if;
9a6dc470
RD
8195 end if;
8196
b6b5cca8
AC
8197 -- Proceed with expansion of mod operator
8198
8199 Left := Left_Opnd (N);
8200 Right := Right_Opnd (N);
8201
5d5e9775
AC
8202 Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
8203 Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
70482933 8204
2c9f8c0a
AC
8205 -- Convert mod to rem if operands are both known to be non-negative, or
8206 -- both known to be non-positive (these are the cases in which rem and
8207 -- mod are the same, see (RM 4.5.5(28-30)). We do this since it is quite
8208 -- likely that this will improve the quality of code, (the operation now
8209 -- corresponds to the hardware remainder), and it does not seem likely
8210 -- that it could be harmful. It also avoids some cases of the elaborate
8211 -- expansion in Modify_Tree_For_C mode below (since Ada rem = C %).
8212
8213 if (LOK and ROK)
8214 and then ((Llo >= 0 and then Rlo >= 0)
cc6f5d75 8215 or else
2c9f8c0a
AC
8216 (Lhi <= 0 and then Rhi <= 0))
8217 then
70482933
RK
8218 Rewrite (N,
8219 Make_Op_Rem (Sloc (N),
8220 Left_Opnd => Left_Opnd (N),
8221 Right_Opnd => Right_Opnd (N)));
8222
685094bf
RD
8223 -- Instead of reanalyzing the node we do the analysis manually. This
8224 -- avoids anomalies when the replacement is done in an instance and
8225 -- is epsilon more efficient.
70482933
RK
8226
8227 Set_Entity (N, Standard_Entity (S_Op_Rem));
fbf5a39b 8228 Set_Etype (N, Typ);
70482933
RK
8229 Set_Do_Division_Check (N, DDC);
8230 Expand_N_Op_Rem (N);
8231 Set_Analyzed (N);
2c9f8c0a 8232 return;
70482933
RK
8233
8234 -- Otherwise, normal mod processing
8235
8236 else
fbf5a39b
AC
8237 -- Apply optimization x mod 1 = 0. We don't really need that with
8238 -- gcc, but it is useful with other back ends (e.g. AAMP), and is
8239 -- certainly harmless.
8240
8241 if Is_Integer_Type (Etype (N))
8242 and then Compile_Time_Known_Value (Right)
8243 and then Expr_Value (Right) = Uint_1
8244 then
abcbd24c
ST
8245 -- Call Remove_Side_Effects to ensure that any side effects in
8246 -- the ignored left operand (in particular function calls to
8247 -- user defined functions) are properly executed.
8248
8249 Remove_Side_Effects (Left);
8250
fbf5a39b
AC
8251 Rewrite (N, Make_Integer_Literal (Loc, 0));
8252 Analyze_And_Resolve (N, Typ);
8253 return;
8254 end if;
8255
2c9f8c0a
AC
8256 -- If we still have a mod operator and we are in Modify_Tree_For_C
8257 -- mode, and we have a signed integer type, then here is where we do
8258 -- the rewrite in terms of Rem. Note this rewrite bypasses the need
8259 -- for the special handling of the annoying case of largest negative
8260 -- number mod minus one.
8261
8262 if Nkind (N) = N_Op_Mod
8263 and then Is_Signed_Integer_Type (Typ)
8264 and then Modify_Tree_For_C
8265 then
8266 -- In the general case, we expand A mod B as
8267
8268 -- Tnn : constant typ := A rem B;
8269 -- ..
8270 -- (if (A >= 0) = (B >= 0) then Tnn
8271 -- elsif Tnn = 0 then 0
8272 -- else Tnn + B)
8273
8274 -- The comparison can be written simply as A >= 0 if we know that
8275 -- B >= 0 which is a very common case.
8276
8277 -- An important optimization is when B is known at compile time
8278 -- to be 2**K for some constant. In this case we can simply AND
8279 -- the left operand with the bit string 2**K-1 (i.e. K 1-bits)
8280 -- and that works for both the positive and negative cases.
8281
8282 declare
8283 P2 : constant Nat := Power_Of_Two (Right);
8284
8285 begin
8286 if P2 /= 0 then
8287 Rewrite (N,
8288 Unchecked_Convert_To (Typ,
8289 Make_Op_And (Loc,
8290 Left_Opnd =>
8291 Unchecked_Convert_To
8292 (Corresponding_Unsigned_Type (Typ), Left),
8293 Right_Opnd =>
8294 Make_Integer_Literal (Loc, 2 ** P2 - 1))));
8295 Analyze_And_Resolve (N, Typ);
8296 return;
8297 end if;
8298 end;
8299
8300 -- Here for the full rewrite
8301
8302 declare
8303 Tnn : constant Entity_Id := Make_Temporary (Sloc (N), 'T', N);
8304 Cmp : Node_Id;
8305
8306 begin
8307 Cmp :=
8308 Make_Op_Ge (Loc,
8309 Left_Opnd => Duplicate_Subexpr_No_Checks (Left),
8310 Right_Opnd => Make_Integer_Literal (Loc, 0));
8311
8312 if not LOK or else Rlo < 0 then
8313 Cmp :=
8314 Make_Op_Eq (Loc,
8315 Left_Opnd => Cmp,
8316 Right_Opnd =>
8317 Make_Op_Ge (Loc,
8318 Left_Opnd => Duplicate_Subexpr_No_Checks (Right),
8319 Right_Opnd => Make_Integer_Literal (Loc, 0)));
8320 end if;
8321
8322 Insert_Action (N,
8323 Make_Object_Declaration (Loc,
8324 Defining_Identifier => Tnn,
8325 Constant_Present => True,
8326 Object_Definition => New_Occurrence_Of (Typ, Loc),
8327 Expression =>
8328 Make_Op_Rem (Loc,
8329 Left_Opnd => Left,
8330 Right_Opnd => Right)));
8331
8332 Rewrite (N,
8333 Make_If_Expression (Loc,
8334 Expressions => New_List (
8335 Cmp,
8336 New_Occurrence_Of (Tnn, Loc),
8337 Make_If_Expression (Loc,
8338 Is_Elsif => True,
8339 Expressions => New_List (
8340 Make_Op_Eq (Loc,
8341 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
8342 Right_Opnd => Make_Integer_Literal (Loc, 0)),
8343 Make_Integer_Literal (Loc, 0),
8344 Make_Op_Add (Loc,
8345 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
8346 Right_Opnd =>
8347 Duplicate_Subexpr_No_Checks (Right)))))));
8348
8349 Analyze_And_Resolve (N, Typ);
8350 return;
8351 end;
8352 end if;
8353
8354 -- Deal with annoying case of largest negative number mod minus one.
8355 -- Gigi may not handle this case correctly, because on some targets,
8356 -- the mod value is computed using a divide instruction which gives
8357 -- an overflow trap for this case.
b9daa96e
AC
8358
8359 -- It would be a bit more efficient to figure out which targets
8360 -- this is really needed for, but in practice it is reasonable
8361 -- to do the following special check in all cases, since it means
8362 -- we get a clearer message, and also the overhead is minimal given
8363 -- that division is expensive in any case.
70482933 8364
685094bf
RD
8365 -- In fact the check is quite easy, if the right operand is -1, then
8366 -- the mod value is always 0, and we can just ignore the left operand
8367 -- completely in this case.
70482933 8368
9a6dc470
RD
8369 -- This only applies if we still have a mod operator. Skip if we
8370 -- have already rewritten this (e.g. in the case of eliminated
8371 -- overflow checks which have driven us into bignum mode).
fbf5a39b 8372
9a6dc470 8373 if Nkind (N) = N_Op_Mod then
70482933 8374
9a6dc470
RD
8375 -- The operand type may be private (e.g. in the expansion of an
8376 -- intrinsic operation) so we must use the underlying type to get
8377 -- the bounds, and convert the literals explicitly.
70482933 8378
9a6dc470
RD
8379 LLB :=
8380 Expr_Value
8381 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
8382
8383 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
761f7dcb 8384 and then ((not LOK) or else (Llo = LLB))
9a6dc470
RD
8385 then
8386 Rewrite (N,
9b16cb57 8387 Make_If_Expression (Loc,
9a6dc470
RD
8388 Expressions => New_List (
8389 Make_Op_Eq (Loc,
8390 Left_Opnd => Duplicate_Subexpr (Right),
8391 Right_Opnd =>
8392 Unchecked_Convert_To (Typ,
8393 Make_Integer_Literal (Loc, -1))),
8394 Unchecked_Convert_To (Typ,
8395 Make_Integer_Literal (Loc, Uint_0)),
8396 Relocate_Node (N))));
8397
8398 Set_Analyzed (Next (Next (First (Expressions (N)))));
8399 Analyze_And_Resolve (N, Typ);
8400 end if;
70482933
RK
8401 end if;
8402 end if;
8403 end Expand_N_Op_Mod;
8404
8405 --------------------------
8406 -- Expand_N_Op_Multiply --
8407 --------------------------
8408
8409 procedure Expand_N_Op_Multiply (N : Node_Id) is
abcbd24c
ST
8410 Loc : constant Source_Ptr := Sloc (N);
8411 Lop : constant Node_Id := Left_Opnd (N);
8412 Rop : constant Node_Id := Right_Opnd (N);
fbf5a39b 8413
abcbd24c 8414 Lp2 : constant Boolean :=
533369aa 8415 Nkind (Lop) = N_Op_Expon and then Is_Power_Of_2_For_Shift (Lop);
abcbd24c 8416 Rp2 : constant Boolean :=
533369aa 8417 Nkind (Rop) = N_Op_Expon and then Is_Power_Of_2_For_Shift (Rop);
fbf5a39b 8418
70482933
RK
8419 Ltyp : constant Entity_Id := Etype (Lop);
8420 Rtyp : constant Entity_Id := Etype (Rop);
8421 Typ : Entity_Id := Etype (N);
8422
8423 begin
8424 Binary_Op_Validity_Checks (N);
8425
b6b5cca8
AC
8426 -- Check for MINIMIZED/ELIMINATED overflow mode
8427
8428 if Minimized_Eliminated_Overflow_Check (N) then
8429 Apply_Arithmetic_Overflow_Check (N);
8430 return;
8431 end if;
8432
70482933
RK
8433 -- Special optimizations for integer types
8434
8435 if Is_Integer_Type (Typ) then
8436
abcbd24c 8437 -- N * 0 = 0 for integer types
70482933 8438
abcbd24c
ST
8439 if Compile_Time_Known_Value (Rop)
8440 and then Expr_Value (Rop) = Uint_0
70482933 8441 then
abcbd24c
ST
8442 -- Call Remove_Side_Effects to ensure that any side effects in
8443 -- the ignored left operand (in particular function calls to
8444 -- user defined functions) are properly executed.
8445
8446 Remove_Side_Effects (Lop);
8447
8448 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
8449 Analyze_And_Resolve (N, Typ);
8450 return;
8451 end if;
8452
8453 -- Similar handling for 0 * N = 0
8454
8455 if Compile_Time_Known_Value (Lop)
8456 and then Expr_Value (Lop) = Uint_0
8457 then
8458 Remove_Side_Effects (Rop);
70482933
RK
8459 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
8460 Analyze_And_Resolve (N, Typ);
8461 return;
8462 end if;
8463
8464 -- N * 1 = 1 * N = N for integer types
8465
fbf5a39b
AC
8466 -- This optimisation is not done if we are going to
8467 -- rewrite the product 1 * 2 ** N to a shift.
8468
8469 if Compile_Time_Known_Value (Rop)
8470 and then Expr_Value (Rop) = Uint_1
8471 and then not Lp2
70482933 8472 then
fbf5a39b 8473 Rewrite (N, Lop);
70482933
RK
8474 return;
8475
fbf5a39b
AC
8476 elsif Compile_Time_Known_Value (Lop)
8477 and then Expr_Value (Lop) = Uint_1
8478 and then not Rp2
70482933 8479 then
fbf5a39b 8480 Rewrite (N, Rop);
70482933
RK
8481 return;
8482 end if;
8483 end if;
8484
70482933
RK
8485 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
8486 -- Is_Power_Of_2_For_Shift is set means that we know that our left
8487 -- operand is an integer, as required for this to work.
8488
fbf5a39b
AC
8489 if Rp2 then
8490 if Lp2 then
70482933 8491
fbf5a39b 8492 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
70482933
RK
8493
8494 Rewrite (N,
8495 Make_Op_Expon (Loc,
8496 Left_Opnd => Make_Integer_Literal (Loc, 2),
8497 Right_Opnd =>
8498 Make_Op_Add (Loc,
8499 Left_Opnd => Right_Opnd (Lop),
8500 Right_Opnd => Right_Opnd (Rop))));
8501 Analyze_And_Resolve (N, Typ);
8502 return;
8503
8504 else
eefe3761
AC
8505 -- If the result is modular, perform the reduction of the result
8506 -- appropriately.
8507
8508 if Is_Modular_Integer_Type (Typ)
8509 and then not Non_Binary_Modulus (Typ)
8510 then
8511 Rewrite (N,
573e5dd6
RD
8512 Make_Op_And (Loc,
8513 Left_Opnd =>
8514 Make_Op_Shift_Left (Loc,
8515 Left_Opnd => Lop,
8516 Right_Opnd =>
8517 Convert_To (Standard_Natural, Right_Opnd (Rop))),
8518 Right_Opnd =>
eefe3761 8519 Make_Integer_Literal (Loc, Modulus (Typ) - 1)));
573e5dd6 8520
eefe3761
AC
8521 else
8522 Rewrite (N,
8523 Make_Op_Shift_Left (Loc,
8524 Left_Opnd => Lop,
8525 Right_Opnd =>
8526 Convert_To (Standard_Natural, Right_Opnd (Rop))));
8527 end if;
8528
70482933
RK
8529 Analyze_And_Resolve (N, Typ);
8530 return;
8531 end if;
8532
8533 -- Same processing for the operands the other way round
8534
fbf5a39b 8535 elsif Lp2 then
eefe3761
AC
8536 if Is_Modular_Integer_Type (Typ)
8537 and then not Non_Binary_Modulus (Typ)
8538 then
8539 Rewrite (N,
573e5dd6
RD
8540 Make_Op_And (Loc,
8541 Left_Opnd =>
8542 Make_Op_Shift_Left (Loc,
8543 Left_Opnd => Rop,
8544 Right_Opnd =>
8545 Convert_To (Standard_Natural, Right_Opnd (Lop))),
8546 Right_Opnd =>
8547 Make_Integer_Literal (Loc, Modulus (Typ) - 1)));
8548
eefe3761
AC
8549 else
8550 Rewrite (N,
8551 Make_Op_Shift_Left (Loc,
8552 Left_Opnd => Rop,
8553 Right_Opnd =>
8554 Convert_To (Standard_Natural, Right_Opnd (Lop))));
8555 end if;
8556
70482933
RK
8557 Analyze_And_Resolve (N, Typ);
8558 return;
8559 end if;
8560
8561 -- Do required fixup of universal fixed operation
8562
8563 if Typ = Universal_Fixed then
8564 Fixup_Universal_Fixed_Operation (N);
8565 Typ := Etype (N);
8566 end if;
8567
8568 -- Multiplications with fixed-point results
8569
8570 if Is_Fixed_Point_Type (Typ) then
8571
685094bf
RD
8572 -- No special processing if Treat_Fixed_As_Integer is set, since from
8573 -- a semantic point of view such operations are simply integer
8574 -- operations and will be treated that way.
70482933
RK
8575
8576 if not Treat_Fixed_As_Integer (N) then
8577
8578 -- Case of fixed * integer => fixed
8579
8580 if Is_Integer_Type (Rtyp) then
8581 Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
8582
8583 -- Case of integer * fixed => fixed
8584
8585 elsif Is_Integer_Type (Ltyp) then
8586 Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
8587
8588 -- Case of fixed * fixed => fixed
8589
8590 else
8591 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
8592 end if;
8593 end if;
8594
685094bf
RD
8595 -- Other cases of multiplication of fixed-point operands. Again we
8596 -- exclude the cases where Treat_Fixed_As_Integer flag is set.
70482933
RK
8597
8598 elsif (Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp))
8599 and then not Treat_Fixed_As_Integer (N)
8600 then
8601 if Is_Integer_Type (Typ) then
8602 Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
8603 else
8604 pragma Assert (Is_Floating_Point_Type (Typ));
8605 Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
8606 end if;
8607
685094bf
RD
8608 -- Mixed-mode operations can appear in a non-static universal context,
8609 -- in which case the integer argument must be converted explicitly.
70482933 8610
533369aa 8611 elsif Typ = Universal_Real and then Is_Integer_Type (Rtyp) then
70482933 8612 Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
70482933
RK
8613 Analyze_And_Resolve (Rop, Universal_Real);
8614
533369aa 8615 elsif Typ = Universal_Real and then Is_Integer_Type (Ltyp) then
70482933 8616 Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
70482933
RK
8617 Analyze_And_Resolve (Lop, Universal_Real);
8618
8619 -- Non-fixed point cases, check software overflow checking required
8620
8621 elsif Is_Signed_Integer_Type (Etype (N)) then
8622 Apply_Arithmetic_Overflow_Check (N);
8623 end if;
dfaff97b
RD
8624
8625 -- Overflow checks for floating-point if -gnateF mode active
8626
8627 Check_Float_Op_Overflow (N);
70482933
RK
8628 end Expand_N_Op_Multiply;
8629
8630 --------------------
8631 -- Expand_N_Op_Ne --
8632 --------------------
8633
70482933 8634 procedure Expand_N_Op_Ne (N : Node_Id) is
f02b8bb8 8635 Typ : constant Entity_Id := Etype (Left_Opnd (N));
70482933
RK
8636
8637 begin
f02b8bb8 8638 -- Case of elementary type with standard operator
70482933 8639
f02b8bb8
RD
8640 if Is_Elementary_Type (Typ)
8641 and then Sloc (Entity (N)) = Standard_Location
8642 then
8643 Binary_Op_Validity_Checks (N);
70482933 8644
456cbfa5 8645 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if
60b68e56 8646 -- means we no longer have a /= operation, we are all done.
456cbfa5
AC
8647
8648 Expand_Compare_Minimize_Eliminate_Overflow (N);
8649
8650 if Nkind (N) /= N_Op_Ne then
8651 return;
8652 end if;
8653
f02b8bb8 8654 -- Boolean types (requiring handling of non-standard case)
70482933 8655
f02b8bb8
RD
8656 if Is_Boolean_Type (Typ) then
8657 Adjust_Condition (Left_Opnd (N));
8658 Adjust_Condition (Right_Opnd (N));
8659 Set_Etype (N, Standard_Boolean);
8660 Adjust_Result_Type (N, Typ);
8661 end if;
fbf5a39b 8662
f02b8bb8
RD
8663 Rewrite_Comparison (N);
8664
f02b8bb8
RD
8665 -- For all cases other than elementary types, we rewrite node as the
8666 -- negation of an equality operation, and reanalyze. The equality to be
8667 -- used is defined in the same scope and has the same signature. This
8668 -- signature must be set explicitly since in an instance it may not have
8669 -- the same visibility as in the generic unit. This avoids duplicating
8670 -- or factoring the complex code for record/array equality tests etc.
8671
8672 else
8673 declare
8674 Loc : constant Source_Ptr := Sloc (N);
8675 Neg : Node_Id;
8676 Ne : constant Entity_Id := Entity (N);
8677
8678 begin
8679 Binary_Op_Validity_Checks (N);
8680
8681 Neg :=
8682 Make_Op_Not (Loc,
8683 Right_Opnd =>
8684 Make_Op_Eq (Loc,
8685 Left_Opnd => Left_Opnd (N),
8686 Right_Opnd => Right_Opnd (N)));
8687 Set_Paren_Count (Right_Opnd (Neg), 1);
8688
8689 if Scope (Ne) /= Standard_Standard then
8690 Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
8691 end if;
8692
4637729f 8693 -- For navigation purposes, we want to treat the inequality as an
f02b8bb8 8694 -- implicit reference to the corresponding equality. Preserve the
4637729f 8695 -- Comes_From_ source flag to generate proper Xref entries.
f02b8bb8
RD
8696
8697 Preserve_Comes_From_Source (Neg, N);
8698 Preserve_Comes_From_Source (Right_Opnd (Neg), N);
8699 Rewrite (N, Neg);
8700 Analyze_And_Resolve (N, Standard_Boolean);
8701 end;
8702 end if;
0580d807
AC
8703
8704 Optimize_Length_Comparison (N);
70482933
RK
8705 end Expand_N_Op_Ne;
8706
8707 ---------------------
8708 -- Expand_N_Op_Not --
8709 ---------------------
8710
685094bf 8711 -- If the argument is other than a Boolean array type, there is no special
7a5b62b0
AC
8712 -- expansion required, except for dealing with validity checks, and non-
8713 -- standard boolean representations.
70482933 8714
7a5b62b0
AC
8715 -- For the packed array case, we call the special routine in Exp_Pakd,
8716 -- except that if the component size is greater than one, we use the
8717 -- standard routine generating a gruesome loop (it is so peculiar to have
8718 -- packed arrays with non-standard Boolean representations anyway, so it
8719 -- does not matter that we do not handle this case efficiently).
70482933 8720
7a5b62b0
AC
8721 -- For the unpacked array case (and for the special packed case where we
8722 -- have non standard Booleans, as discussed above), we generate and insert
8723 -- into the tree the following function definition:
70482933
RK
8724
8725 -- function Nnnn (A : arr) is
8726 -- B : arr;
8727 -- begin
8728 -- for J in a'range loop
8729 -- B (J) := not A (J);
8730 -- end loop;
8731 -- return B;
8732 -- end Nnnn;
8733
8734 -- Here arr is the actual subtype of the parameter (and hence always
8735 -- constrained). Then we replace the not with a call to this function.
8736
8737 procedure Expand_N_Op_Not (N : Node_Id) is
8738 Loc : constant Source_Ptr := Sloc (N);
8739 Typ : constant Entity_Id := Etype (N);
8740 Opnd : Node_Id;
8741 Arr : Entity_Id;
8742 A : Entity_Id;
8743 B : Entity_Id;
8744 J : Entity_Id;
8745 A_J : Node_Id;
8746 B_J : Node_Id;
8747
8748 Func_Name : Entity_Id;
8749 Loop_Statement : Node_Id;
8750
8751 begin
8752 Unary_Op_Validity_Checks (N);
8753
8754 -- For boolean operand, deal with non-standard booleans
8755
8756 if Is_Boolean_Type (Typ) then
8757 Adjust_Condition (Right_Opnd (N));
8758 Set_Etype (N, Standard_Boolean);
8759 Adjust_Result_Type (N, Typ);
8760 return;
8761 end if;
8762
da94696d 8763 -- Only array types need any other processing
70482933 8764
da94696d 8765 if not Is_Array_Type (Typ) then
70482933
RK
8766 return;
8767 end if;
8768
a9d8907c
JM
8769 -- Case of array operand. If bit packed with a component size of 1,
8770 -- handle it in Exp_Pakd if the operand is known to be aligned.
70482933 8771
a9d8907c
JM
8772 if Is_Bit_Packed_Array (Typ)
8773 and then Component_Size (Typ) = 1
8774 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
8775 then
70482933
RK
8776 Expand_Packed_Not (N);
8777 return;
8778 end if;
8779
fbf5a39b
AC
8780 -- Case of array operand which is not bit-packed. If the context is
8781 -- a safe assignment, call in-place operation, If context is a larger
8782 -- boolean expression in the context of a safe assignment, expansion is
8783 -- done by enclosing operation.
70482933
RK
8784
8785 Opnd := Relocate_Node (Right_Opnd (N));
8786 Convert_To_Actual_Subtype (Opnd);
8787 Arr := Etype (Opnd);
8788 Ensure_Defined (Arr, N);
b4592168 8789 Silly_Boolean_Array_Not_Test (N, Arr);
70482933 8790
fbf5a39b
AC
8791 if Nkind (Parent (N)) = N_Assignment_Statement then
8792 if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
8793 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
8794 return;
8795
5e1c00fa 8796 -- Special case the negation of a binary operation
fbf5a39b 8797
303b4d58 8798 elsif Nkind_In (Opnd, N_Op_And, N_Op_Or, N_Op_Xor)
fbf5a39b 8799 and then Safe_In_Place_Array_Op
303b4d58 8800 (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
fbf5a39b
AC
8801 then
8802 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
8803 return;
8804 end if;
8805
8806 elsif Nkind (Parent (N)) in N_Binary_Op
8807 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
8808 then
8809 declare
8810 Op1 : constant Node_Id := Left_Opnd (Parent (N));
8811 Op2 : constant Node_Id := Right_Opnd (Parent (N));
8812 Lhs : constant Node_Id := Name (Parent (Parent (N)));
8813
8814 begin
8815 if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
fbf5a39b 8816
aa9a7dd7
AC
8817 -- (not A) op (not B) can be reduced to a single call
8818
8819 if N = Op1 and then Nkind (Op2) = N_Op_Not then
fbf5a39b
AC
8820 return;
8821
bed8af19
AC
8822 elsif N = Op2 and then Nkind (Op1) = N_Op_Not then
8823 return;
8824
aa9a7dd7 8825 -- A xor (not B) can also be special-cased
fbf5a39b 8826
aa9a7dd7 8827 elsif N = Op2 and then Nkind (Parent (N)) = N_Op_Xor then
fbf5a39b
AC
8828 return;
8829 end if;
8830 end if;
8831 end;
8832 end if;
8833
70482933
RK
8834 A := Make_Defining_Identifier (Loc, Name_uA);
8835 B := Make_Defining_Identifier (Loc, Name_uB);
8836 J := Make_Defining_Identifier (Loc, Name_uJ);
8837
8838 A_J :=
8839 Make_Indexed_Component (Loc,
e4494292
RD
8840 Prefix => New_Occurrence_Of (A, Loc),
8841 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
8842
8843 B_J :=
8844 Make_Indexed_Component (Loc,
e4494292
RD
8845 Prefix => New_Occurrence_Of (B, Loc),
8846 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
8847
8848 Loop_Statement :=
8849 Make_Implicit_Loop_Statement (N,
8850 Identifier => Empty,
8851
8852 Iteration_Scheme =>
8853 Make_Iteration_Scheme (Loc,
8854 Loop_Parameter_Specification =>
8855 Make_Loop_Parameter_Specification (Loc,
0d901290 8856 Defining_Identifier => J,
70482933
RK
8857 Discrete_Subtype_Definition =>
8858 Make_Attribute_Reference (Loc,
0d901290 8859 Prefix => Make_Identifier (Loc, Chars (A)),
70482933
RK
8860 Attribute_Name => Name_Range))),
8861
8862 Statements => New_List (
8863 Make_Assignment_Statement (Loc,
8864 Name => B_J,
8865 Expression => Make_Op_Not (Loc, A_J))));
8866
191fcb3a 8867 Func_Name := Make_Temporary (Loc, 'N');
70482933
RK
8868 Set_Is_Inlined (Func_Name);
8869
8870 Insert_Action (N,
8871 Make_Subprogram_Body (Loc,
8872 Specification =>
8873 Make_Function_Specification (Loc,
8874 Defining_Unit_Name => Func_Name,
8875 Parameter_Specifications => New_List (
8876 Make_Parameter_Specification (Loc,
8877 Defining_Identifier => A,
e4494292
RD
8878 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
8879 Result_Definition => New_Occurrence_Of (Typ, Loc)),
70482933
RK
8880
8881 Declarations => New_List (
8882 Make_Object_Declaration (Loc,
8883 Defining_Identifier => B,
e4494292 8884 Object_Definition => New_Occurrence_Of (Arr, Loc))),
70482933
RK
8885
8886 Handled_Statement_Sequence =>
8887 Make_Handled_Sequence_Of_Statements (Loc,
8888 Statements => New_List (
8889 Loop_Statement,
d766cee3 8890 Make_Simple_Return_Statement (Loc,
0d901290 8891 Expression => Make_Identifier (Loc, Chars (B)))))));
70482933
RK
8892
8893 Rewrite (N,
8894 Make_Function_Call (Loc,
e4494292 8895 Name => New_Occurrence_Of (Func_Name, Loc),
70482933
RK
8896 Parameter_Associations => New_List (Opnd)));
8897
8898 Analyze_And_Resolve (N, Typ);
8899 end Expand_N_Op_Not;
8900
8901 --------------------
8902 -- Expand_N_Op_Or --
8903 --------------------
8904
8905 procedure Expand_N_Op_Or (N : Node_Id) is
8906 Typ : constant Entity_Id := Etype (N);
8907
8908 begin
8909 Binary_Op_Validity_Checks (N);
8910
8911 if Is_Array_Type (Etype (N)) then
8912 Expand_Boolean_Operator (N);
8913
8914 elsif Is_Boolean_Type (Etype (N)) then
f2d10a02
AC
8915 Adjust_Condition (Left_Opnd (N));
8916 Adjust_Condition (Right_Opnd (N));
8917 Set_Etype (N, Standard_Boolean);
8918 Adjust_Result_Type (N, Typ);
437f8c1e
AC
8919
8920 elsif Is_Intrinsic_Subprogram (Entity (N)) then
8921 Expand_Intrinsic_Call (N, Entity (N));
8922
70482933
RK
8923 end if;
8924 end Expand_N_Op_Or;
8925
8926 ----------------------
8927 -- Expand_N_Op_Plus --
8928 ----------------------
8929
8930 procedure Expand_N_Op_Plus (N : Node_Id) is
8931 begin
8932 Unary_Op_Validity_Checks (N);
b6b5cca8
AC
8933
8934 -- Check for MINIMIZED/ELIMINATED overflow mode
8935
8936 if Minimized_Eliminated_Overflow_Check (N) then
8937 Apply_Arithmetic_Overflow_Check (N);
8938 return;
8939 end if;
70482933
RK
8940 end Expand_N_Op_Plus;
8941
8942 ---------------------
8943 -- Expand_N_Op_Rem --
8944 ---------------------
8945
8946 procedure Expand_N_Op_Rem (N : Node_Id) is
8947 Loc : constant Source_Ptr := Sloc (N);
fbf5a39b 8948 Typ : constant Entity_Id := Etype (N);
70482933 8949
b6b5cca8
AC
8950 Left : Node_Id;
8951 Right : Node_Id;
70482933 8952
5d5e9775
AC
8953 Lo : Uint;
8954 Hi : Uint;
8955 OK : Boolean;
70482933 8956
5d5e9775
AC
8957 Lneg : Boolean;
8958 Rneg : Boolean;
8959 -- Set if corresponding operand can be negative
8960
8961 pragma Unreferenced (Hi);
1033834f 8962
70482933
RK
8963 begin
8964 Binary_Op_Validity_Checks (N);
8965
b6b5cca8
AC
8966 -- Check for MINIMIZED/ELIMINATED overflow mode
8967
8968 if Minimized_Eliminated_Overflow_Check (N) then
8969 Apply_Arithmetic_Overflow_Check (N);
8970 return;
8971 end if;
8972
70482933 8973 if Is_Integer_Type (Etype (N)) then
a91e9ac7 8974 Apply_Divide_Checks (N);
b6b5cca8
AC
8975
8976 -- All done if we don't have a REM any more, which can happen as a
8977 -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
8978
8979 if Nkind (N) /= N_Op_Rem then
8980 return;
8981 end if;
70482933
RK
8982 end if;
8983
b6b5cca8
AC
8984 -- Proceed with expansion of REM
8985
8986 Left := Left_Opnd (N);
8987 Right := Right_Opnd (N);
8988
685094bf
RD
8989 -- Apply optimization x rem 1 = 0. We don't really need that with gcc,
8990 -- but it is useful with other back ends (e.g. AAMP), and is certainly
8991 -- harmless.
fbf5a39b
AC
8992
8993 if Is_Integer_Type (Etype (N))
8994 and then Compile_Time_Known_Value (Right)
8995 and then Expr_Value (Right) = Uint_1
8996 then
abcbd24c
ST
8997 -- Call Remove_Side_Effects to ensure that any side effects in the
8998 -- ignored left operand (in particular function calls to user defined
8999 -- functions) are properly executed.
9000
9001 Remove_Side_Effects (Left);
9002
fbf5a39b
AC
9003 Rewrite (N, Make_Integer_Literal (Loc, 0));
9004 Analyze_And_Resolve (N, Typ);
9005 return;
9006 end if;
9007
685094bf 9008 -- Deal with annoying case of largest negative number remainder minus
b9daa96e
AC
9009 -- one. Gigi may not handle this case correctly, because on some
9010 -- targets, the mod value is computed using a divide instruction
9011 -- which gives an overflow trap for this case.
9012
9013 -- It would be a bit more efficient to figure out which targets this
9014 -- is really needed for, but in practice it is reasonable to do the
9015 -- following special check in all cases, since it means we get a clearer
9016 -- message, and also the overhead is minimal given that division is
9017 -- expensive in any case.
70482933 9018
685094bf
RD
9019 -- In fact the check is quite easy, if the right operand is -1, then
9020 -- the remainder is always 0, and we can just ignore the left operand
9021 -- completely in this case.
70482933 9022
5d5e9775
AC
9023 Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
9024 Lneg := (not OK) or else Lo < 0;
fbf5a39b 9025
5d5e9775
AC
9026 Determine_Range (Left, OK, Lo, Hi, Assume_Valid => True);
9027 Rneg := (not OK) or else Lo < 0;
fbf5a39b 9028
5d5e9775
AC
9029 -- We won't mess with trying to find out if the left operand can really
9030 -- be the largest negative number (that's a pain in the case of private
9031 -- types and this is really marginal). We will just assume that we need
9032 -- the test if the left operand can be negative at all.
fbf5a39b 9033
5d5e9775 9034 if Lneg and Rneg then
70482933 9035 Rewrite (N,
9b16cb57 9036 Make_If_Expression (Loc,
70482933
RK
9037 Expressions => New_List (
9038 Make_Op_Eq (Loc,
0d901290 9039 Left_Opnd => Duplicate_Subexpr (Right),
70482933 9040 Right_Opnd =>
0d901290 9041 Unchecked_Convert_To (Typ, Make_Integer_Literal (Loc, -1))),
70482933 9042
fbf5a39b
AC
9043 Unchecked_Convert_To (Typ,
9044 Make_Integer_Literal (Loc, Uint_0)),
70482933
RK
9045
9046 Relocate_Node (N))));
9047
9048 Set_Analyzed (Next (Next (First (Expressions (N)))));
9049 Analyze_And_Resolve (N, Typ);
9050 end if;
9051 end Expand_N_Op_Rem;
9052
9053 -----------------------------
9054 -- Expand_N_Op_Rotate_Left --
9055 -----------------------------
9056
9057 procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
9058 begin
9059 Binary_Op_Validity_Checks (N);
5216b599
AC
9060
9061 -- If we are in Modify_Tree_For_C mode, there is no rotate left in C,
9062 -- so we rewrite in terms of logical shifts
9063
9064 -- Shift_Left (Num, Bits) or Shift_Right (num, Esize - Bits)
9065
9066 -- where Bits is the shift count mod Esize (the mod operation here
9067 -- deals with ludicrous large shift counts, which are apparently OK).
9068
a95f708e 9069 -- What about nonbinary modulus ???
5216b599
AC
9070
9071 declare
9072 Loc : constant Source_Ptr := Sloc (N);
9073 Rtp : constant Entity_Id := Etype (Right_Opnd (N));
9074 Typ : constant Entity_Id := Etype (N);
9075
9076 begin
9077 if Modify_Tree_For_C then
9078 Rewrite (Right_Opnd (N),
9079 Make_Op_Rem (Loc,
9080 Left_Opnd => Relocate_Node (Right_Opnd (N)),
9081 Right_Opnd => Make_Integer_Literal (Loc, Esize (Typ))));
9082
9083 Analyze_And_Resolve (Right_Opnd (N), Rtp);
9084
9085 Rewrite (N,
9086 Make_Op_Or (Loc,
9087 Left_Opnd =>
9088 Make_Op_Shift_Left (Loc,
9089 Left_Opnd => Left_Opnd (N),
9090 Right_Opnd => Right_Opnd (N)),
e09a5598 9091
5216b599
AC
9092 Right_Opnd =>
9093 Make_Op_Shift_Right (Loc,
9094 Left_Opnd => Duplicate_Subexpr_No_Checks (Left_Opnd (N)),
9095 Right_Opnd =>
9096 Make_Op_Subtract (Loc,
9097 Left_Opnd => Make_Integer_Literal (Loc, Esize (Typ)),
9098 Right_Opnd =>
9099 Duplicate_Subexpr_No_Checks (Right_Opnd (N))))));
9100
9101 Analyze_And_Resolve (N, Typ);
9102 end if;
9103 end;
70482933
RK
9104 end Expand_N_Op_Rotate_Left;
9105
9106 ------------------------------
9107 -- Expand_N_Op_Rotate_Right --
9108 ------------------------------
9109
9110 procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
9111 begin
9112 Binary_Op_Validity_Checks (N);
5216b599
AC
9113
9114 -- If we are in Modify_Tree_For_C mode, there is no rotate right in C,
9115 -- so we rewrite in terms of logical shifts
9116
9117 -- Shift_Right (Num, Bits) or Shift_Left (num, Esize - Bits)
9118
9119 -- where Bits is the shift count mod Esize (the mod operation here
9120 -- deals with ludicrous large shift counts, which are apparently OK).
9121
a95f708e 9122 -- What about nonbinary modulus ???
5216b599
AC
9123
9124 declare
9125 Loc : constant Source_Ptr := Sloc (N);
9126 Rtp : constant Entity_Id := Etype (Right_Opnd (N));
9127 Typ : constant Entity_Id := Etype (N);
9128
9129 begin
9130 Rewrite (Right_Opnd (N),
9131 Make_Op_Rem (Loc,
9132 Left_Opnd => Relocate_Node (Right_Opnd (N)),
9133 Right_Opnd => Make_Integer_Literal (Loc, Esize (Typ))));
9134
9135 Analyze_And_Resolve (Right_Opnd (N), Rtp);
9136
9137 if Modify_Tree_For_C then
9138 Rewrite (N,
9139 Make_Op_Or (Loc,
9140 Left_Opnd =>
9141 Make_Op_Shift_Right (Loc,
9142 Left_Opnd => Left_Opnd (N),
9143 Right_Opnd => Right_Opnd (N)),
e09a5598 9144
5216b599
AC
9145 Right_Opnd =>
9146 Make_Op_Shift_Left (Loc,
9147 Left_Opnd => Duplicate_Subexpr_No_Checks (Left_Opnd (N)),
9148 Right_Opnd =>
9149 Make_Op_Subtract (Loc,
9150 Left_Opnd => Make_Integer_Literal (Loc, Esize (Typ)),
9151 Right_Opnd =>
9152 Duplicate_Subexpr_No_Checks (Right_Opnd (N))))));
9153
9154 Analyze_And_Resolve (N, Typ);
9155 end if;
9156 end;
70482933
RK
9157 end Expand_N_Op_Rotate_Right;
9158
9159 ----------------------------
9160 -- Expand_N_Op_Shift_Left --
9161 ----------------------------
9162
e09a5598
AC
9163 -- Note: nothing in this routine depends on left as opposed to right shifts
9164 -- so we share the routine for expanding shift right operations.
9165
70482933
RK
9166 procedure Expand_N_Op_Shift_Left (N : Node_Id) is
9167 begin
9168 Binary_Op_Validity_Checks (N);
e09a5598
AC
9169
9170 -- If we are in Modify_Tree_For_C mode, then ensure that the right
9171 -- operand is not greater than the word size (since that would not
9172 -- be defined properly by the corresponding C shift operator).
9173
9174 if Modify_Tree_For_C then
9175 declare
9176 Right : constant Node_Id := Right_Opnd (N);
9177 Loc : constant Source_Ptr := Sloc (Right);
9178 Typ : constant Entity_Id := Etype (N);
9179 Siz : constant Uint := Esize (Typ);
9180 Orig : Node_Id;
9181 OK : Boolean;
9182 Lo : Uint;
9183 Hi : Uint;
9184
9185 begin
9186 if Compile_Time_Known_Value (Right) then
9187 if Expr_Value (Right) >= Siz then
9188 Rewrite (N, Make_Integer_Literal (Loc, 0));
9189 Analyze_And_Resolve (N, Typ);
9190 end if;
9191
9192 -- Not compile time known, find range
9193
9194 else
9195 Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
9196
9197 -- Nothing to do if known to be OK range, otherwise expand
9198
9199 if not OK or else Hi >= Siz then
9200
9201 -- Prevent recursion on copy of shift node
9202
9203 Orig := Relocate_Node (N);
9204 Set_Analyzed (Orig);
9205
9206 -- Now do the rewrite
9207
9208 Rewrite (N,
9209 Make_If_Expression (Loc,
9210 Expressions => New_List (
9211 Make_Op_Ge (Loc,
9212 Left_Opnd => Duplicate_Subexpr_Move_Checks (Right),
9213 Right_Opnd => Make_Integer_Literal (Loc, Siz)),
9214 Make_Integer_Literal (Loc, 0),
9215 Orig)));
9216 Analyze_And_Resolve (N, Typ);
9217 end if;
9218 end if;
9219 end;
9220 end if;
70482933
RK
9221 end Expand_N_Op_Shift_Left;
9222
9223 -----------------------------
9224 -- Expand_N_Op_Shift_Right --
9225 -----------------------------
9226
9227 procedure Expand_N_Op_Shift_Right (N : Node_Id) is
9228 begin
e09a5598
AC
9229 -- Share shift left circuit
9230
9231 Expand_N_Op_Shift_Left (N);
70482933
RK
9232 end Expand_N_Op_Shift_Right;
9233
9234 ----------------------------------------
9235 -- Expand_N_Op_Shift_Right_Arithmetic --
9236 ----------------------------------------
9237
9238 procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
9239 begin
9240 Binary_Op_Validity_Checks (N);
5216b599
AC
9241
9242 -- If we are in Modify_Tree_For_C mode, there is no shift right
9243 -- arithmetic in C, so we rewrite in terms of logical shifts.
9244
9245 -- Shift_Right (Num, Bits) or
9246 -- (if Num >= Sign
9247 -- then not (Shift_Right (Mask, bits))
9248 -- else 0)
9249
9250 -- Here Mask is all 1 bits (2**size - 1), and Sign is 2**(size - 1)
9251
9252 -- Note: in almost all C compilers it would work to just shift a
9253 -- signed integer right, but it's undefined and we cannot rely on it.
9254
e09a5598
AC
9255 -- Note: the above works fine for shift counts greater than or equal
9256 -- to the word size, since in this case (not (Shift_Right (Mask, bits)))
9257 -- generates all 1'bits.
9258
a95f708e 9259 -- What about nonbinary modulus ???
5216b599
AC
9260
9261 declare
9262 Loc : constant Source_Ptr := Sloc (N);
9263 Typ : constant Entity_Id := Etype (N);
9264 Sign : constant Uint := 2 ** (Esize (Typ) - 1);
9265 Mask : constant Uint := (2 ** Esize (Typ)) - 1;
9266 Left : constant Node_Id := Left_Opnd (N);
9267 Right : constant Node_Id := Right_Opnd (N);
9268 Maskx : Node_Id;
9269
9270 begin
9271 if Modify_Tree_For_C then
9272
9273 -- Here if not (Shift_Right (Mask, bits)) can be computed at
9274 -- compile time as a single constant.
9275
9276 if Compile_Time_Known_Value (Right) then
9277 declare
9278 Val : constant Uint := Expr_Value (Right);
9279
9280 begin
9281 if Val >= Esize (Typ) then
9282 Maskx := Make_Integer_Literal (Loc, Mask);
9283
9284 else
9285 Maskx :=
9286 Make_Integer_Literal (Loc,
9287 Intval => Mask - (Mask / (2 ** Expr_Value (Right))));
9288 end if;
9289 end;
9290
9291 else
9292 Maskx :=
9293 Make_Op_Not (Loc,
9294 Right_Opnd =>
9295 Make_Op_Shift_Right (Loc,
9296 Left_Opnd => Make_Integer_Literal (Loc, Mask),
9297 Right_Opnd => Duplicate_Subexpr_No_Checks (Right)));
9298 end if;
9299
9300 -- Now do the rewrite
9301
9302 Rewrite (N,
9303 Make_Op_Or (Loc,
9304 Left_Opnd =>
9305 Make_Op_Shift_Right (Loc,
9306 Left_Opnd => Left,
9307 Right_Opnd => Right),
9308 Right_Opnd =>
9309 Make_If_Expression (Loc,
9310 Expressions => New_List (
9311 Make_Op_Ge (Loc,
9312 Left_Opnd => Duplicate_Subexpr_No_Checks (Left),
9313 Right_Opnd => Make_Integer_Literal (Loc, Sign)),
9314 Maskx,
9315 Make_Integer_Literal (Loc, 0)))));
9316 Analyze_And_Resolve (N, Typ);
9317 end if;
9318 end;
70482933
RK
9319 end Expand_N_Op_Shift_Right_Arithmetic;
9320
9321 --------------------------
9322 -- Expand_N_Op_Subtract --
9323 --------------------------
9324
9325 procedure Expand_N_Op_Subtract (N : Node_Id) is
9326 Typ : constant Entity_Id := Etype (N);
9327
9328 begin
9329 Binary_Op_Validity_Checks (N);
9330
b6b5cca8
AC
9331 -- Check for MINIMIZED/ELIMINATED overflow mode
9332
9333 if Minimized_Eliminated_Overflow_Check (N) then
9334 Apply_Arithmetic_Overflow_Check (N);
9335 return;
9336 end if;
9337
70482933
RK
9338 -- N - 0 = N for integer types
9339
9340 if Is_Integer_Type (Typ)
9341 and then Compile_Time_Known_Value (Right_Opnd (N))
9342 and then Expr_Value (Right_Opnd (N)) = 0
9343 then
9344 Rewrite (N, Left_Opnd (N));
9345 return;
9346 end if;
9347
8fc789c8 9348 -- Arithmetic overflow checks for signed integer/fixed point types
70482933 9349
761f7dcb 9350 if Is_Signed_Integer_Type (Typ) or else Is_Fixed_Point_Type (Typ) then
70482933 9351 Apply_Arithmetic_Overflow_Check (N);
70482933 9352 end if;
dfaff97b
RD
9353
9354 -- Overflow checks for floating-point if -gnateF mode active
9355
9356 Check_Float_Op_Overflow (N);
70482933
RK
9357 end Expand_N_Op_Subtract;
9358
9359 ---------------------
9360 -- Expand_N_Op_Xor --
9361 ---------------------
9362
9363 procedure Expand_N_Op_Xor (N : Node_Id) is
9364 Typ : constant Entity_Id := Etype (N);
9365
9366 begin
9367 Binary_Op_Validity_Checks (N);
9368
9369 if Is_Array_Type (Etype (N)) then
9370 Expand_Boolean_Operator (N);
9371
9372 elsif Is_Boolean_Type (Etype (N)) then
9373 Adjust_Condition (Left_Opnd (N));
9374 Adjust_Condition (Right_Opnd (N));
9375 Set_Etype (N, Standard_Boolean);
9376 Adjust_Result_Type (N, Typ);
437f8c1e
AC
9377
9378 elsif Is_Intrinsic_Subprogram (Entity (N)) then
9379 Expand_Intrinsic_Call (N, Entity (N));
9380
70482933
RK
9381 end if;
9382 end Expand_N_Op_Xor;
9383
9384 ----------------------
9385 -- Expand_N_Or_Else --
9386 ----------------------
9387
5875f8d6
AC
9388 procedure Expand_N_Or_Else (N : Node_Id)
9389 renames Expand_Short_Circuit_Operator;
70482933
RK
9390
9391 -----------------------------------
9392 -- Expand_N_Qualified_Expression --
9393 -----------------------------------
9394
9395 procedure Expand_N_Qualified_Expression (N : Node_Id) is
9396 Operand : constant Node_Id := Expression (N);
9397 Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
9398
9399 begin
f82944b7
JM
9400 -- Do validity check if validity checking operands
9401
533369aa 9402 if Validity_Checks_On and Validity_Check_Operands then
f82944b7
JM
9403 Ensure_Valid (Operand);
9404 end if;
9405
9406 -- Apply possible constraint check
9407
70482933 9408 Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
d79e621a
GD
9409
9410 if Do_Range_Check (Operand) then
9411 Set_Do_Range_Check (Operand, False);
9412 Generate_Range_Check (Operand, Target_Type, CE_Range_Check_Failed);
9413 end if;
70482933
RK
9414 end Expand_N_Qualified_Expression;
9415
a961aa79
AC
9416 ------------------------------------
9417 -- Expand_N_Quantified_Expression --
9418 ------------------------------------
9419
c0f136cd
AC
9420 -- We expand:
9421
9422 -- for all X in range => Cond
a961aa79 9423
c0f136cd 9424 -- into:
a961aa79 9425
c0f136cd
AC
9426 -- T := True;
9427 -- for X in range loop
9428 -- if not Cond then
9429 -- T := False;
9430 -- exit;
9431 -- end if;
9432 -- end loop;
90c63b09 9433
36504e5f 9434 -- Similarly, an existentially quantified expression:
90c63b09 9435
c0f136cd 9436 -- for some X in range => Cond
90c63b09 9437
c0f136cd 9438 -- becomes:
90c63b09 9439
c0f136cd
AC
9440 -- T := False;
9441 -- for X in range loop
9442 -- if Cond then
9443 -- T := True;
9444 -- exit;
9445 -- end if;
9446 -- end loop;
90c63b09 9447
c0f136cd
AC
9448 -- In both cases, the iteration may be over a container in which case it is
9449 -- given by an iterator specification, not a loop parameter specification.
a961aa79 9450
c0f136cd 9451 procedure Expand_N_Quantified_Expression (N : Node_Id) is
804670f1
AC
9452 Actions : constant List_Id := New_List;
9453 For_All : constant Boolean := All_Present (N);
9454 Iter_Spec : constant Node_Id := Iterator_Specification (N);
9455 Loc : constant Source_Ptr := Sloc (N);
9456 Loop_Spec : constant Node_Id := Loop_Parameter_Specification (N);
9457 Cond : Node_Id;
9458 Flag : Entity_Id;
9459 Scheme : Node_Id;
9460 Stmts : List_Id;
c56a9ba4 9461
a961aa79 9462 begin
804670f1
AC
9463 -- Create the declaration of the flag which tracks the status of the
9464 -- quantified expression. Generate:
011f9d5d 9465
804670f1 9466 -- Flag : Boolean := (True | False);
011f9d5d 9467
804670f1 9468 Flag := Make_Temporary (Loc, 'T', N);
011f9d5d 9469
804670f1 9470 Append_To (Actions,
90c63b09 9471 Make_Object_Declaration (Loc,
804670f1 9472 Defining_Identifier => Flag,
c0f136cd
AC
9473 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
9474 Expression =>
804670f1
AC
9475 New_Occurrence_Of (Boolean_Literals (For_All), Loc)));
9476
9477 -- Construct the circuitry which tracks the status of the quantified
9478 -- expression. Generate:
9479
9480 -- if [not] Cond then
9481 -- Flag := (False | True);
9482 -- exit;
9483 -- end if;
a961aa79 9484
c0f136cd 9485 Cond := Relocate_Node (Condition (N));
a961aa79 9486
804670f1 9487 if For_All then
c0f136cd 9488 Cond := Make_Op_Not (Loc, Cond);
a961aa79
AC
9489 end if;
9490
804670f1 9491 Stmts := New_List (
c0f136cd
AC
9492 Make_Implicit_If_Statement (N,
9493 Condition => Cond,
9494 Then_Statements => New_List (
9495 Make_Assignment_Statement (Loc,
804670f1 9496 Name => New_Occurrence_Of (Flag, Loc),
c0f136cd 9497 Expression =>
804670f1
AC
9498 New_Occurrence_Of (Boolean_Literals (not For_All), Loc)),
9499 Make_Exit_Statement (Loc))));
9500
9501 -- Build the loop equivalent of the quantified expression
c0f136cd 9502
804670f1
AC
9503 if Present (Iter_Spec) then
9504 Scheme :=
011f9d5d 9505 Make_Iteration_Scheme (Loc,
804670f1 9506 Iterator_Specification => Iter_Spec);
c56a9ba4 9507 else
804670f1 9508 Scheme :=
011f9d5d 9509 Make_Iteration_Scheme (Loc,
804670f1 9510 Loop_Parameter_Specification => Loop_Spec);
c56a9ba4
AC
9511 end if;
9512
a961aa79
AC
9513 Append_To (Actions,
9514 Make_Loop_Statement (Loc,
804670f1
AC
9515 Iteration_Scheme => Scheme,
9516 Statements => Stmts,
c0f136cd 9517 End_Label => Empty));
a961aa79 9518
804670f1
AC
9519 -- Transform the quantified expression
9520
a961aa79
AC
9521 Rewrite (N,
9522 Make_Expression_With_Actions (Loc,
804670f1 9523 Expression => New_Occurrence_Of (Flag, Loc),
a961aa79 9524 Actions => Actions));
a961aa79
AC
9525 Analyze_And_Resolve (N, Standard_Boolean);
9526 end Expand_N_Quantified_Expression;
9527
70482933
RK
9528 ---------------------------------
9529 -- Expand_N_Selected_Component --
9530 ---------------------------------
9531
70482933
RK
9532 procedure Expand_N_Selected_Component (N : Node_Id) is
9533 Loc : constant Source_Ptr := Sloc (N);
9534 Par : constant Node_Id := Parent (N);
9535 P : constant Node_Id := Prefix (N);
03eb6036 9536 S : constant Node_Id := Selector_Name (N);
fbf5a39b 9537 Ptyp : Entity_Id := Underlying_Type (Etype (P));
70482933 9538 Disc : Entity_Id;
70482933 9539 New_N : Node_Id;
fbf5a39b 9540 Dcon : Elmt_Id;
d606f1df 9541 Dval : Node_Id;
70482933
RK
9542
9543 function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
9544 -- Gigi needs a temporary for prefixes that depend on a discriminant,
9545 -- unless the context of an assignment can provide size information.
fbf5a39b
AC
9546 -- Don't we have a general routine that does this???
9547
53f29d4f
AC
9548 function Is_Subtype_Declaration return Boolean;
9549 -- The replacement of a discriminant reference by its value is required
4317e442
AC
9550 -- if this is part of the initialization of an temporary generated by a
9551 -- change of representation. This shows up as the construction of a
53f29d4f 9552 -- discriminant constraint for a subtype declared at the same point as
4317e442
AC
9553 -- the entity in the prefix of the selected component. We recognize this
9554 -- case when the context of the reference is:
9555 -- subtype ST is T(Obj.D);
9556 -- where the entity for Obj comes from source, and ST has the same sloc.
53f29d4f 9557
fbf5a39b
AC
9558 -----------------------
9559 -- In_Left_Hand_Side --
9560 -----------------------
70482933
RK
9561
9562 function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
9563 begin
fbf5a39b 9564 return (Nkind (Parent (Comp)) = N_Assignment_Statement
90c63b09 9565 and then Comp = Name (Parent (Comp)))
fbf5a39b 9566 or else (Present (Parent (Comp))
90c63b09
AC
9567 and then Nkind (Parent (Comp)) in N_Subexpr
9568 and then In_Left_Hand_Side (Parent (Comp)));
70482933
RK
9569 end In_Left_Hand_Side;
9570
53f29d4f
AC
9571 -----------------------------
9572 -- Is_Subtype_Declaration --
9573 -----------------------------
9574
9575 function Is_Subtype_Declaration return Boolean is
9576 Par : constant Node_Id := Parent (N);
53f29d4f
AC
9577 begin
9578 return
9579 Nkind (Par) = N_Index_Or_Discriminant_Constraint
9580 and then Nkind (Parent (Parent (Par))) = N_Subtype_Declaration
9581 and then Comes_From_Source (Entity (Prefix (N)))
9582 and then Sloc (Par) = Sloc (Entity (Prefix (N)));
9583 end Is_Subtype_Declaration;
9584
fbf5a39b
AC
9585 -- Start of processing for Expand_N_Selected_Component
9586
70482933 9587 begin
fbf5a39b
AC
9588 -- Insert explicit dereference if required
9589
9590 if Is_Access_Type (Ptyp) then
702d2020
AC
9591
9592 -- First set prefix type to proper access type, in case it currently
9593 -- has a private (non-access) view of this type.
9594
9595 Set_Etype (P, Ptyp);
9596
fbf5a39b 9597 Insert_Explicit_Dereference (P);
e6f69614 9598 Analyze_And_Resolve (P, Designated_Type (Ptyp));
fbf5a39b
AC
9599
9600 if Ekind (Etype (P)) = E_Private_Subtype
9601 and then Is_For_Access_Subtype (Etype (P))
9602 then
9603 Set_Etype (P, Base_Type (Etype (P)));
9604 end if;
9605
9606 Ptyp := Etype (P);
9607 end if;
9608
9609 -- Deal with discriminant check required
9610
70482933 9611 if Do_Discriminant_Check (N) then
03eb6036
AC
9612 if Present (Discriminant_Checking_Func
9613 (Original_Record_Component (Entity (S))))
9614 then
9615 -- Present the discriminant checking function to the backend, so
9616 -- that it can inline the call to the function.
9617
9618 Add_Inlined_Body
9619 (Discriminant_Checking_Func
cf27c5a2
EB
9620 (Original_Record_Component (Entity (S))),
9621 N);
70482933 9622
03eb6036 9623 -- Now reset the flag and generate the call
70482933 9624
03eb6036
AC
9625 Set_Do_Discriminant_Check (N, False);
9626 Generate_Discriminant_Check (N);
70482933 9627
03eb6036
AC
9628 -- In the case of Unchecked_Union, no discriminant checking is
9629 -- actually performed.
70482933 9630
03eb6036
AC
9631 else
9632 Set_Do_Discriminant_Check (N, False);
9633 end if;
70482933
RK
9634 end if;
9635
b4592168
GD
9636 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
9637 -- function, then additional actuals must be passed.
9638
0791fbe9 9639 if Ada_Version >= Ada_2005
b4592168
GD
9640 and then Is_Build_In_Place_Function_Call (P)
9641 then
9642 Make_Build_In_Place_Call_In_Anonymous_Context (P);
9643 end if;
9644
fbf5a39b
AC
9645 -- Gigi cannot handle unchecked conversions that are the prefix of a
9646 -- selected component with discriminants. This must be checked during
9647 -- expansion, because during analysis the type of the selector is not
9648 -- known at the point the prefix is analyzed. If the conversion is the
9649 -- target of an assignment, then we cannot force the evaluation.
70482933
RK
9650
9651 if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
9652 and then Has_Discriminants (Etype (N))
9653 and then not In_Left_Hand_Side (N)
9654 then
9655 Force_Evaluation (Prefix (N));
9656 end if;
9657
9658 -- Remaining processing applies only if selector is a discriminant
9659
9660 if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
9661
9662 -- If the selector is a discriminant of a constrained record type,
fbf5a39b
AC
9663 -- we may be able to rewrite the expression with the actual value
9664 -- of the discriminant, a useful optimization in some cases.
70482933
RK
9665
9666 if Is_Record_Type (Ptyp)
9667 and then Has_Discriminants (Ptyp)
9668 and then Is_Constrained (Ptyp)
70482933 9669 then
fbf5a39b 9670 -- Do this optimization for discrete types only, and not for
a90bd866 9671 -- access types (access discriminants get us into trouble).
70482933 9672
fbf5a39b
AC
9673 if not Is_Discrete_Type (Etype (N)) then
9674 null;
9675
9676 -- Don't do this on the left hand of an assignment statement.
0d901290
AC
9677 -- Normally one would think that references like this would not
9678 -- occur, but they do in generated code, and mean that we really
a90bd866 9679 -- do want to assign the discriminant.
fbf5a39b
AC
9680
9681 elsif Nkind (Par) = N_Assignment_Statement
9682 and then Name (Par) = N
9683 then
9684 null;
9685
685094bf 9686 -- Don't do this optimization for the prefix of an attribute or
e2534738 9687 -- the name of an object renaming declaration since these are
685094bf 9688 -- contexts where we do not want the value anyway.
fbf5a39b
AC
9689
9690 elsif (Nkind (Par) = N_Attribute_Reference
533369aa 9691 and then Prefix (Par) = N)
fbf5a39b
AC
9692 or else Is_Renamed_Object (N)
9693 then
9694 null;
9695
9696 -- Don't do this optimization if we are within the code for a
9697 -- discriminant check, since the whole point of such a check may
a90bd866 9698 -- be to verify the condition on which the code below depends.
fbf5a39b
AC
9699
9700 elsif Is_In_Discriminant_Check (N) then
9701 null;
9702
9703 -- Green light to see if we can do the optimization. There is
685094bf
RD
9704 -- still one condition that inhibits the optimization below but
9705 -- now is the time to check the particular discriminant.
fbf5a39b
AC
9706
9707 else
685094bf
RD
9708 -- Loop through discriminants to find the matching discriminant
9709 -- constraint to see if we can copy it.
fbf5a39b
AC
9710
9711 Disc := First_Discriminant (Ptyp);
9712 Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
9713 Discr_Loop : while Present (Dcon) loop
d606f1df 9714 Dval := Node (Dcon);
fbf5a39b 9715
bd949ee2
RD
9716 -- Check if this is the matching discriminant and if the
9717 -- discriminant value is simple enough to make sense to
9718 -- copy. We don't want to copy complex expressions, and
9719 -- indeed to do so can cause trouble (before we put in
9720 -- this guard, a discriminant expression containing an
e7d897b8 9721 -- AND THEN was copied, causing problems for coverage
c228a069 9722 -- analysis tools).
bd949ee2 9723
53f29d4f
AC
9724 -- However, if the reference is part of the initialization
9725 -- code generated for an object declaration, we must use
9726 -- the discriminant value from the subtype constraint,
9727 -- because the selected component may be a reference to the
9728 -- object being initialized, whose discriminant is not yet
9729 -- set. This only happens in complex cases involving changes
9730 -- or representation.
9731
bd949ee2
RD
9732 if Disc = Entity (Selector_Name (N))
9733 and then (Is_Entity_Name (Dval)
170b2989
AC
9734 or else Compile_Time_Known_Value (Dval)
9735 or else Is_Subtype_Declaration)
bd949ee2 9736 then
fbf5a39b
AC
9737 -- Here we have the matching discriminant. Check for
9738 -- the case of a discriminant of a component that is
9739 -- constrained by an outer discriminant, which cannot
9740 -- be optimized away.
9741
d606f1df
AC
9742 if Denotes_Discriminant
9743 (Dval, Check_Concurrent => True)
9744 then
9745 exit Discr_Loop;
9746
9747 elsif Nkind (Original_Node (Dval)) = N_Selected_Component
9748 and then
9749 Denotes_Discriminant
9750 (Selector_Name (Original_Node (Dval)), True)
9751 then
9752 exit Discr_Loop;
9753
9754 -- Do not retrieve value if constraint is not static. It
9755 -- is generally not useful, and the constraint may be a
9756 -- rewritten outer discriminant in which case it is in
9757 -- fact incorrect.
9758
9759 elsif Is_Entity_Name (Dval)
d606f1df 9760 and then
533369aa
AC
9761 Nkind (Parent (Entity (Dval))) = N_Object_Declaration
9762 and then Present (Expression (Parent (Entity (Dval))))
9763 and then not
edab6088 9764 Is_OK_Static_Expression
d606f1df 9765 (Expression (Parent (Entity (Dval))))
fbf5a39b
AC
9766 then
9767 exit Discr_Loop;
70482933 9768
685094bf
RD
9769 -- In the context of a case statement, the expression may
9770 -- have the base type of the discriminant, and we need to
9771 -- preserve the constraint to avoid spurious errors on
9772 -- missing cases.
70482933 9773
fbf5a39b 9774 elsif Nkind (Parent (N)) = N_Case_Statement
d606f1df 9775 and then Etype (Dval) /= Etype (Disc)
70482933
RK
9776 then
9777 Rewrite (N,
9778 Make_Qualified_Expression (Loc,
fbf5a39b
AC
9779 Subtype_Mark =>
9780 New_Occurrence_Of (Etype (Disc), Loc),
9781 Expression =>
d606f1df 9782 New_Copy_Tree (Dval)));
ffe9aba8 9783 Analyze_And_Resolve (N, Etype (Disc));
fbf5a39b
AC
9784
9785 -- In case that comes out as a static expression,
9786 -- reset it (a selected component is never static).
9787
9788 Set_Is_Static_Expression (N, False);
9789 return;
9790
9791 -- Otherwise we can just copy the constraint, but the
a90bd866 9792 -- result is certainly not static. In some cases the
ffe9aba8
AC
9793 -- discriminant constraint has been analyzed in the
9794 -- context of the original subtype indication, but for
9795 -- itypes the constraint might not have been analyzed
9796 -- yet, and this must be done now.
fbf5a39b 9797
70482933 9798 else
d606f1df 9799 Rewrite (N, New_Copy_Tree (Dval));
ffe9aba8 9800 Analyze_And_Resolve (N);
fbf5a39b
AC
9801 Set_Is_Static_Expression (N, False);
9802 return;
70482933 9803 end if;
70482933
RK
9804 end if;
9805
fbf5a39b
AC
9806 Next_Elmt (Dcon);
9807 Next_Discriminant (Disc);
9808 end loop Discr_Loop;
70482933 9809
fbf5a39b
AC
9810 -- Note: the above loop should always find a matching
9811 -- discriminant, but if it does not, we just missed an
c228a069
AC
9812 -- optimization due to some glitch (perhaps a previous
9813 -- error), so ignore.
fbf5a39b
AC
9814
9815 end if;
70482933
RK
9816 end if;
9817
9818 -- The only remaining processing is in the case of a discriminant of
9819 -- a concurrent object, where we rewrite the prefix to denote the
9820 -- corresponding record type. If the type is derived and has renamed
9821 -- discriminants, use corresponding discriminant, which is the one
9822 -- that appears in the corresponding record.
9823
9824 if not Is_Concurrent_Type (Ptyp) then
9825 return;
9826 end if;
9827
9828 Disc := Entity (Selector_Name (N));
9829
9830 if Is_Derived_Type (Ptyp)
9831 and then Present (Corresponding_Discriminant (Disc))
9832 then
9833 Disc := Corresponding_Discriminant (Disc);
9834 end if;
9835
9836 New_N :=
9837 Make_Selected_Component (Loc,
9838 Prefix =>
9839 Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
9840 New_Copy_Tree (P)),
9841 Selector_Name => Make_Identifier (Loc, Chars (Disc)));
9842
9843 Rewrite (N, New_N);
9844 Analyze (N);
9845 end if;
5972791c 9846
73fe1679 9847 -- Set Atomic_Sync_Required if necessary for atomic component
5972791c 9848
73fe1679
AC
9849 if Nkind (N) = N_Selected_Component then
9850 declare
9851 E : constant Entity_Id := Entity (Selector_Name (N));
9852 Set : Boolean;
9853
9854 begin
9855 -- If component is atomic, but type is not, setting depends on
9856 -- disable/enable state for the component.
9857
9858 if Is_Atomic (E) and then not Is_Atomic (Etype (E)) then
9859 Set := not Atomic_Synchronization_Disabled (E);
9860
9861 -- If component is not atomic, but its type is atomic, setting
9862 -- depends on disable/enable state for the type.
9863
9864 elsif not Is_Atomic (E) and then Is_Atomic (Etype (E)) then
9865 Set := not Atomic_Synchronization_Disabled (Etype (E));
9866
9867 -- If both component and type are atomic, we disable if either
9868 -- component or its type have sync disabled.
9869
9870 elsif Is_Atomic (E) and then Is_Atomic (Etype (E)) then
9871 Set := (not Atomic_Synchronization_Disabled (E))
9872 and then
9873 (not Atomic_Synchronization_Disabled (Etype (E)));
9874
9875 else
9876 Set := False;
9877 end if;
9878
9879 -- Set flag if required
9880
9881 if Set then
9882 Activate_Atomic_Synchronization (N);
9883 end if;
9884 end;
5972791c 9885 end if;
70482933
RK
9886 end Expand_N_Selected_Component;
9887
9888 --------------------
9889 -- Expand_N_Slice --
9890 --------------------
9891
9892 procedure Expand_N_Slice (N : Node_Id) is
5ff90f08
AC
9893 Loc : constant Source_Ptr := Sloc (N);
9894 Typ : constant Entity_Id := Etype (N);
fbf5a39b 9895
81a5b587 9896 function Is_Procedure_Actual (N : Node_Id) return Boolean;
685094bf
RD
9897 -- Check whether the argument is an actual for a procedure call, in
9898 -- which case the expansion of a bit-packed slice is deferred until the
9899 -- call itself is expanded. The reason this is required is that we might
9900 -- have an IN OUT or OUT parameter, and the copy out is essential, and
9901 -- that copy out would be missed if we created a temporary here in
9902 -- Expand_N_Slice. Note that we don't bother to test specifically for an
9903 -- IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
9904 -- is harmless to defer expansion in the IN case, since the call
9905 -- processing will still generate the appropriate copy in operation,
9906 -- which will take care of the slice.
81a5b587 9907
b01bf852 9908 procedure Make_Temporary_For_Slice;
685094bf
RD
9909 -- Create a named variable for the value of the slice, in cases where
9910 -- the back-end cannot handle it properly, e.g. when packed types or
9911 -- unaligned slices are involved.
fbf5a39b 9912
81a5b587
AC
9913 -------------------------
9914 -- Is_Procedure_Actual --
9915 -------------------------
9916
9917 function Is_Procedure_Actual (N : Node_Id) return Boolean is
9918 Par : Node_Id := Parent (N);
08aa9a4a 9919
81a5b587 9920 begin
81a5b587 9921 loop
c6a60aa1
RD
9922 -- If our parent is a procedure call we can return
9923
81a5b587
AC
9924 if Nkind (Par) = N_Procedure_Call_Statement then
9925 return True;
6b6fcd3e 9926
685094bf
RD
9927 -- If our parent is a type conversion, keep climbing the tree,
9928 -- since a type conversion can be a procedure actual. Also keep
9929 -- climbing if parameter association or a qualified expression,
9930 -- since these are additional cases that do can appear on
9931 -- procedure actuals.
6b6fcd3e 9932
303b4d58
AC
9933 elsif Nkind_In (Par, N_Type_Conversion,
9934 N_Parameter_Association,
9935 N_Qualified_Expression)
c6a60aa1 9936 then
81a5b587 9937 Par := Parent (Par);
c6a60aa1
RD
9938
9939 -- Any other case is not what we are looking for
9940
9941 else
9942 return False;
81a5b587
AC
9943 end if;
9944 end loop;
81a5b587
AC
9945 end Is_Procedure_Actual;
9946
b01bf852
AC
9947 ------------------------------
9948 -- Make_Temporary_For_Slice --
9949 ------------------------------
fbf5a39b 9950
b01bf852 9951 procedure Make_Temporary_For_Slice is
b01bf852 9952 Ent : constant Entity_Id := Make_Temporary (Loc, 'T', N);
5ff90f08 9953 Decl : Node_Id;
13d923cc 9954
fbf5a39b
AC
9955 begin
9956 Decl :=
9957 Make_Object_Declaration (Loc,
9958 Defining_Identifier => Ent,
9959 Object_Definition => New_Occurrence_Of (Typ, Loc));
9960
9961 Set_No_Initialization (Decl);
9962
9963 Insert_Actions (N, New_List (
9964 Decl,
9965 Make_Assignment_Statement (Loc,
5ff90f08 9966 Name => New_Occurrence_Of (Ent, Loc),
fbf5a39b
AC
9967 Expression => Relocate_Node (N))));
9968
9969 Rewrite (N, New_Occurrence_Of (Ent, Loc));
9970 Analyze_And_Resolve (N, Typ);
b01bf852 9971 end Make_Temporary_For_Slice;
fbf5a39b 9972
5ff90f08
AC
9973 -- Local variables
9974
800da977
AC
9975 Pref : constant Node_Id := Prefix (N);
9976 Pref_Typ : Entity_Id := Etype (Pref);
5ff90f08 9977
fbf5a39b 9978 -- Start of processing for Expand_N_Slice
70482933
RK
9979
9980 begin
9981 -- Special handling for access types
9982
5ff90f08
AC
9983 if Is_Access_Type (Pref_Typ) then
9984 Pref_Typ := Designated_Type (Pref_Typ);
70482933 9985
5ff90f08 9986 Rewrite (Pref,
e6f69614 9987 Make_Explicit_Dereference (Sloc (N),
5ff90f08 9988 Prefix => Relocate_Node (Pref)));
70482933 9989
5ff90f08 9990 Analyze_And_Resolve (Pref, Pref_Typ);
70482933
RK
9991 end if;
9992
b4592168
GD
9993 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
9994 -- function, then additional actuals must be passed.
9995
0791fbe9 9996 if Ada_Version >= Ada_2005
5ff90f08 9997 and then Is_Build_In_Place_Function_Call (Pref)
b4592168 9998 then
5ff90f08 9999 Make_Build_In_Place_Call_In_Anonymous_Context (Pref);
b4592168
GD
10000 end if;
10001
70482933
RK
10002 -- The remaining case to be handled is packed slices. We can leave
10003 -- packed slices as they are in the following situations:
10004
10005 -- 1. Right or left side of an assignment (we can handle this
10006 -- situation correctly in the assignment statement expansion).
10007
685094bf
RD
10008 -- 2. Prefix of indexed component (the slide is optimized away in this
10009 -- case, see the start of Expand_N_Slice.)
70482933 10010
685094bf
RD
10011 -- 3. Object renaming declaration, since we want the name of the
10012 -- slice, not the value.
70482933 10013
685094bf
RD
10014 -- 4. Argument to procedure call, since copy-in/copy-out handling may
10015 -- be required, and this is handled in the expansion of call
10016 -- itself.
70482933 10017
685094bf
RD
10018 -- 5. Prefix of an address attribute (this is an error which is caught
10019 -- elsewhere, and the expansion would interfere with generating the
10020 -- error message).
70482933 10021
81a5b587 10022 if not Is_Packed (Typ) then
08aa9a4a 10023
685094bf
RD
10024 -- Apply transformation for actuals of a function call, where
10025 -- Expand_Actuals is not used.
81a5b587
AC
10026
10027 if Nkind (Parent (N)) = N_Function_Call
10028 and then Is_Possibly_Unaligned_Slice (N)
10029 then
b01bf852 10030 Make_Temporary_For_Slice;
81a5b587
AC
10031 end if;
10032
10033 elsif Nkind (Parent (N)) = N_Assignment_Statement
10034 or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
533369aa 10035 and then Parent (N) = Name (Parent (Parent (N))))
70482933 10036 then
81a5b587 10037 return;
70482933 10038
81a5b587
AC
10039 elsif Nkind (Parent (N)) = N_Indexed_Component
10040 or else Is_Renamed_Object (N)
10041 or else Is_Procedure_Actual (N)
10042 then
10043 return;
70482933 10044
91b1417d
AC
10045 elsif Nkind (Parent (N)) = N_Attribute_Reference
10046 and then Attribute_Name (Parent (N)) = Name_Address
fbf5a39b 10047 then
81a5b587
AC
10048 return;
10049
10050 else
b01bf852 10051 Make_Temporary_For_Slice;
70482933
RK
10052 end if;
10053 end Expand_N_Slice;
10054
10055 ------------------------------
10056 -- Expand_N_Type_Conversion --
10057 ------------------------------
10058
10059 procedure Expand_N_Type_Conversion (N : Node_Id) is
10060 Loc : constant Source_Ptr := Sloc (N);
10061 Operand : constant Node_Id := Expression (N);
10062 Target_Type : constant Entity_Id := Etype (N);
10063 Operand_Type : Entity_Id := Etype (Operand);
10064
10065 procedure Handle_Changed_Representation;
685094bf
RD
10066 -- This is called in the case of record and array type conversions to
10067 -- see if there is a change of representation to be handled. Change of
10068 -- representation is actually handled at the assignment statement level,
10069 -- and what this procedure does is rewrite node N conversion as an
10070 -- assignment to temporary. If there is no change of representation,
10071 -- then the conversion node is unchanged.
70482933 10072
426908f8
RD
10073 procedure Raise_Accessibility_Error;
10074 -- Called when we know that an accessibility check will fail. Rewrites
10075 -- node N to an appropriate raise statement and outputs warning msgs.
91669e7e
AC
10076 -- The Etype of the raise node is set to Target_Type. Note that in this
10077 -- case the rest of the processing should be skipped (i.e. the call to
10078 -- this procedure will be followed by "goto Done").
426908f8 10079
70482933
RK
10080 procedure Real_Range_Check;
10081 -- Handles generation of range check for real target value
10082
d15f9422
AC
10083 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean;
10084 -- True iff Present (Effective_Extra_Accessibility (Id)) successfully
10085 -- evaluates to True.
10086
70482933
RK
10087 -----------------------------------
10088 -- Handle_Changed_Representation --
10089 -----------------------------------
10090
10091 procedure Handle_Changed_Representation is
10092 Temp : Entity_Id;
10093 Decl : Node_Id;
10094 Odef : Node_Id;
10095 Disc : Node_Id;
10096 N_Ix : Node_Id;
10097 Cons : List_Id;
10098
10099 begin
f82944b7 10100 -- Nothing else to do if no change of representation
70482933
RK
10101
10102 if Same_Representation (Operand_Type, Target_Type) then
10103 return;
10104
10105 -- The real change of representation work is done by the assignment
10106 -- statement processing. So if this type conversion is appearing as
10107 -- the expression of an assignment statement, nothing needs to be
10108 -- done to the conversion.
10109
10110 elsif Nkind (Parent (N)) = N_Assignment_Statement then
10111 return;
10112
10113 -- Otherwise we need to generate a temporary variable, and do the
10114 -- change of representation assignment into that temporary variable.
10115 -- The conversion is then replaced by a reference to this variable.
10116
10117 else
10118 Cons := No_List;
10119
685094bf
RD
10120 -- If type is unconstrained we have to add a constraint, copied
10121 -- from the actual value of the left hand side.
70482933
RK
10122
10123 if not Is_Constrained (Target_Type) then
10124 if Has_Discriminants (Operand_Type) then
10125 Disc := First_Discriminant (Operand_Type);
fbf5a39b
AC
10126
10127 if Disc /= First_Stored_Discriminant (Operand_Type) then
10128 Disc := First_Stored_Discriminant (Operand_Type);
10129 end if;
10130
70482933
RK
10131 Cons := New_List;
10132 while Present (Disc) loop
10133 Append_To (Cons,
10134 Make_Selected_Component (Loc,
7675ad4f
AC
10135 Prefix =>
10136 Duplicate_Subexpr_Move_Checks (Operand),
70482933
RK
10137 Selector_Name =>
10138 Make_Identifier (Loc, Chars (Disc))));
10139 Next_Discriminant (Disc);
10140 end loop;
10141
10142 elsif Is_Array_Type (Operand_Type) then
10143 N_Ix := First_Index (Target_Type);
10144 Cons := New_List;
10145
10146 for J in 1 .. Number_Dimensions (Operand_Type) loop
10147
10148 -- We convert the bounds explicitly. We use an unchecked
10149 -- conversion because bounds checks are done elsewhere.
10150
10151 Append_To (Cons,
10152 Make_Range (Loc,
10153 Low_Bound =>
10154 Unchecked_Convert_To (Etype (N_Ix),
10155 Make_Attribute_Reference (Loc,
10156 Prefix =>
fbf5a39b 10157 Duplicate_Subexpr_No_Checks
70482933
RK
10158 (Operand, Name_Req => True),
10159 Attribute_Name => Name_First,
10160 Expressions => New_List (
10161 Make_Integer_Literal (Loc, J)))),
10162
10163 High_Bound =>
10164 Unchecked_Convert_To (Etype (N_Ix),
10165 Make_Attribute_Reference (Loc,
10166 Prefix =>
fbf5a39b 10167 Duplicate_Subexpr_No_Checks
70482933
RK
10168 (Operand, Name_Req => True),
10169 Attribute_Name => Name_Last,
10170 Expressions => New_List (
10171 Make_Integer_Literal (Loc, J))))));
10172
10173 Next_Index (N_Ix);
10174 end loop;
10175 end if;
10176 end if;
10177
10178 Odef := New_Occurrence_Of (Target_Type, Loc);
10179
10180 if Present (Cons) then
10181 Odef :=
10182 Make_Subtype_Indication (Loc,
10183 Subtype_Mark => Odef,
10184 Constraint =>
10185 Make_Index_Or_Discriminant_Constraint (Loc,
10186 Constraints => Cons));
10187 end if;
10188
191fcb3a 10189 Temp := Make_Temporary (Loc, 'C');
70482933
RK
10190 Decl :=
10191 Make_Object_Declaration (Loc,
10192 Defining_Identifier => Temp,
10193 Object_Definition => Odef);
10194
10195 Set_No_Initialization (Decl, True);
10196
10197 -- Insert required actions. It is essential to suppress checks
10198 -- since we have suppressed default initialization, which means
10199 -- that the variable we create may have no discriminants.
10200
10201 Insert_Actions (N,
10202 New_List (
10203 Decl,
10204 Make_Assignment_Statement (Loc,
10205 Name => New_Occurrence_Of (Temp, Loc),
10206 Expression => Relocate_Node (N))),
10207 Suppress => All_Checks);
10208
10209 Rewrite (N, New_Occurrence_Of (Temp, Loc));
10210 return;
10211 end if;
10212 end Handle_Changed_Representation;
10213
426908f8
RD
10214 -------------------------------
10215 -- Raise_Accessibility_Error --
10216 -------------------------------
10217
10218 procedure Raise_Accessibility_Error is
10219 begin
43417b90 10220 Error_Msg_Warn := SPARK_Mode /= On;
426908f8
RD
10221 Rewrite (N,
10222 Make_Raise_Program_Error (Sloc (N),
10223 Reason => PE_Accessibility_Check_Failed));
10224 Set_Etype (N, Target_Type);
10225
4a28b181
AC
10226 Error_Msg_N ("<<accessibility check failure", N);
10227 Error_Msg_NE ("\<<& [", N, Standard_Program_Error);
426908f8
RD
10228 end Raise_Accessibility_Error;
10229
70482933
RK
10230 ----------------------
10231 -- Real_Range_Check --
10232 ----------------------
10233
685094bf
RD
10234 -- Case of conversions to floating-point or fixed-point. If range checks
10235 -- are enabled and the target type has a range constraint, we convert:
70482933
RK
10236
10237 -- typ (x)
10238
10239 -- to
10240
10241 -- Tnn : typ'Base := typ'Base (x);
10242 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
10243 -- Tnn
10244
685094bf
RD
10245 -- This is necessary when there is a conversion of integer to float or
10246 -- to fixed-point to ensure that the correct checks are made. It is not
10247 -- necessary for float to float where it is enough to simply set the
10248 -- Do_Range_Check flag.
fbf5a39b 10249
70482933
RK
10250 procedure Real_Range_Check is
10251 Btyp : constant Entity_Id := Base_Type (Target_Type);
10252 Lo : constant Node_Id := Type_Low_Bound (Target_Type);
10253 Hi : constant Node_Id := Type_High_Bound (Target_Type);
fbf5a39b 10254 Xtyp : constant Entity_Id := Etype (Operand);
70482933
RK
10255 Conv : Node_Id;
10256 Tnn : Entity_Id;
10257
10258 begin
10259 -- Nothing to do if conversion was rewritten
10260
10261 if Nkind (N) /= N_Type_Conversion then
10262 return;
10263 end if;
10264
685094bf
RD
10265 -- Nothing to do if range checks suppressed, or target has the same
10266 -- range as the base type (or is the base type).
70482933
RK
10267
10268 if Range_Checks_Suppressed (Target_Type)
533369aa 10269 or else (Lo = Type_Low_Bound (Btyp)
70482933
RK
10270 and then
10271 Hi = Type_High_Bound (Btyp))
10272 then
10273 return;
10274 end if;
10275
685094bf
RD
10276 -- Nothing to do if expression is an entity on which checks have been
10277 -- suppressed.
70482933 10278
fbf5a39b
AC
10279 if Is_Entity_Name (Operand)
10280 and then Range_Checks_Suppressed (Entity (Operand))
10281 then
10282 return;
10283 end if;
10284
685094bf
RD
10285 -- Nothing to do if bounds are all static and we can tell that the
10286 -- expression is within the bounds of the target. Note that if the
10287 -- operand is of an unconstrained floating-point type, then we do
10288 -- not trust it to be in range (might be infinite)
fbf5a39b
AC
10289
10290 declare
f02b8bb8
RD
10291 S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
10292 S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
fbf5a39b
AC
10293
10294 begin
10295 if (not Is_Floating_Point_Type (Xtyp)
10296 or else Is_Constrained (Xtyp))
10297 and then Compile_Time_Known_Value (S_Lo)
10298 and then Compile_Time_Known_Value (S_Hi)
10299 and then Compile_Time_Known_Value (Hi)
10300 and then Compile_Time_Known_Value (Lo)
10301 then
10302 declare
10303 D_Lov : constant Ureal := Expr_Value_R (Lo);
10304 D_Hiv : constant Ureal := Expr_Value_R (Hi);
10305 S_Lov : Ureal;
10306 S_Hiv : Ureal;
10307
10308 begin
10309 if Is_Real_Type (Xtyp) then
10310 S_Lov := Expr_Value_R (S_Lo);
10311 S_Hiv := Expr_Value_R (S_Hi);
10312 else
10313 S_Lov := UR_From_Uint (Expr_Value (S_Lo));
10314 S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
10315 end if;
10316
10317 if D_Hiv > D_Lov
10318 and then S_Lov >= D_Lov
10319 and then S_Hiv <= D_Hiv
10320 then
8b034336
AC
10321 -- Unset the range check flag on the current value of
10322 -- Expression (N), since the captured Operand may have
10323 -- been rewritten (such as for the case of a conversion
10324 -- to a fixed-point type).
10325
10326 Set_Do_Range_Check (Expression (N), False);
10327
fbf5a39b
AC
10328 return;
10329 end if;
10330 end;
10331 end if;
10332 end;
10333
10334 -- For float to float conversions, we are done
10335
10336 if Is_Floating_Point_Type (Xtyp)
10337 and then
10338 Is_Floating_Point_Type (Btyp)
70482933
RK
10339 then
10340 return;
10341 end if;
10342
fbf5a39b 10343 -- Otherwise rewrite the conversion as described above
70482933
RK
10344
10345 Conv := Relocate_Node (N);
eaa826f8 10346 Rewrite (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
70482933
RK
10347 Set_Etype (Conv, Btyp);
10348
f02b8bb8
RD
10349 -- Enable overflow except for case of integer to float conversions,
10350 -- where it is never required, since we can never have overflow in
10351 -- this case.
70482933 10352
fbf5a39b
AC
10353 if not Is_Integer_Type (Etype (Operand)) then
10354 Enable_Overflow_Check (Conv);
70482933
RK
10355 end if;
10356
191fcb3a 10357 Tnn := Make_Temporary (Loc, 'T', Conv);
70482933
RK
10358
10359 Insert_Actions (N, New_List (
10360 Make_Object_Declaration (Loc,
10361 Defining_Identifier => Tnn,
10362 Object_Definition => New_Occurrence_Of (Btyp, Loc),
0ac2a660
AC
10363 Constant_Present => True,
10364 Expression => Conv),
70482933
RK
10365
10366 Make_Raise_Constraint_Error (Loc,
07fc65c4
GB
10367 Condition =>
10368 Make_Or_Else (Loc,
10369 Left_Opnd =>
10370 Make_Op_Lt (Loc,
10371 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
10372 Right_Opnd =>
10373 Make_Attribute_Reference (Loc,
10374 Attribute_Name => Name_First,
10375 Prefix =>
10376 New_Occurrence_Of (Target_Type, Loc))),
70482933 10377
07fc65c4
GB
10378 Right_Opnd =>
10379 Make_Op_Gt (Loc,
10380 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
10381 Right_Opnd =>
10382 Make_Attribute_Reference (Loc,
10383 Attribute_Name => Name_Last,
10384 Prefix =>
10385 New_Occurrence_Of (Target_Type, Loc)))),
10386 Reason => CE_Range_Check_Failed)));
70482933
RK
10387
10388 Rewrite (N, New_Occurrence_Of (Tnn, Loc));
10389 Analyze_And_Resolve (N, Btyp);
10390 end Real_Range_Check;
10391
d15f9422
AC
10392 -----------------------------
10393 -- Has_Extra_Accessibility --
10394 -----------------------------
10395
10396 -- Returns true for a formal of an anonymous access type or for
10397 -- an Ada 2012-style stand-alone object of an anonymous access type.
10398
10399 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean is
10400 begin
10401 if Is_Formal (Id) or else Ekind_In (Id, E_Constant, E_Variable) then
10402 return Present (Effective_Extra_Accessibility (Id));
10403 else
10404 return False;
10405 end if;
10406 end Has_Extra_Accessibility;
10407
70482933
RK
10408 -- Start of processing for Expand_N_Type_Conversion
10409
10410 begin
83851b23 10411 -- First remove check marks put by the semantic analysis on the type
b2502161
AC
10412 -- conversion between array types. We need these checks, and they will
10413 -- be generated by this expansion routine, but we do not depend on these
10414 -- flags being set, and since we do intend to expand the checks in the
10415 -- front end, we don't want them on the tree passed to the back end.
83851b23
AC
10416
10417 if Is_Array_Type (Target_Type) then
10418 if Is_Constrained (Target_Type) then
10419 Set_Do_Length_Check (N, False);
10420 else
10421 Set_Do_Range_Check (Operand, False);
10422 end if;
10423 end if;
10424
685094bf 10425 -- Nothing at all to do if conversion is to the identical type so remove
76efd572
AC
10426 -- the conversion completely, it is useless, except that it may carry
10427 -- an Assignment_OK attribute, which must be propagated to the operand.
70482933
RK
10428
10429 if Operand_Type = Target_Type then
7b00e31d
AC
10430 if Assignment_OK (N) then
10431 Set_Assignment_OK (Operand);
10432 end if;
10433
fbf5a39b 10434 Rewrite (N, Relocate_Node (Operand));
e606088a 10435 goto Done;
70482933
RK
10436 end if;
10437
685094bf
RD
10438 -- Nothing to do if this is the second argument of read. This is a
10439 -- "backwards" conversion that will be handled by the specialized code
10440 -- in attribute processing.
70482933
RK
10441
10442 if Nkind (Parent (N)) = N_Attribute_Reference
10443 and then Attribute_Name (Parent (N)) = Name_Read
10444 and then Next (First (Expressions (Parent (N)))) = N
10445 then
e606088a
AC
10446 goto Done;
10447 end if;
10448
10449 -- Check for case of converting to a type that has an invariant
10450 -- associated with it. This required an invariant check. We convert
10451
10452 -- typ (expr)
10453
10454 -- into
10455
10456 -- do invariant_check (typ (expr)) in typ (expr);
10457
10458 -- using Duplicate_Subexpr to avoid multiple side effects
10459
10460 -- Note: the Comes_From_Source check, and then the resetting of this
10461 -- flag prevents what would otherwise be an infinite recursion.
10462
fd0ff1cf
RD
10463 if Has_Invariants (Target_Type)
10464 and then Present (Invariant_Procedure (Target_Type))
e606088a
AC
10465 and then Comes_From_Source (N)
10466 then
10467 Set_Comes_From_Source (N, False);
10468 Rewrite (N,
10469 Make_Expression_With_Actions (Loc,
10470 Actions => New_List (
10471 Make_Invariant_Call (Duplicate_Subexpr (N))),
10472 Expression => Duplicate_Subexpr_No_Checks (N)));
10473 Analyze_And_Resolve (N, Target_Type);
10474 goto Done;
70482933
RK
10475 end if;
10476
10477 -- Here if we may need to expand conversion
10478
eaa826f8
RD
10479 -- If the operand of the type conversion is an arithmetic operation on
10480 -- signed integers, and the based type of the signed integer type in
10481 -- question is smaller than Standard.Integer, we promote both of the
10482 -- operands to type Integer.
10483
10484 -- For example, if we have
10485
10486 -- target-type (opnd1 + opnd2)
10487
10488 -- and opnd1 and opnd2 are of type short integer, then we rewrite
10489 -- this as:
10490
10491 -- target-type (integer(opnd1) + integer(opnd2))
10492
10493 -- We do this because we are always allowed to compute in a larger type
10494 -- if we do the right thing with the result, and in this case we are
10495 -- going to do a conversion which will do an appropriate check to make
10496 -- sure that things are in range of the target type in any case. This
10497 -- avoids some unnecessary intermediate overflows.
10498
dfcfdc0a
AC
10499 -- We might consider a similar transformation in the case where the
10500 -- target is a real type or a 64-bit integer type, and the operand
10501 -- is an arithmetic operation using a 32-bit integer type. However,
10502 -- we do not bother with this case, because it could cause significant
308e6f3a 10503 -- inefficiencies on 32-bit machines. On a 64-bit machine it would be
dfcfdc0a
AC
10504 -- much cheaper, but we don't want different behavior on 32-bit and
10505 -- 64-bit machines. Note that the exclusion of the 64-bit case also
10506 -- handles the configurable run-time cases where 64-bit arithmetic
10507 -- may simply be unavailable.
eaa826f8
RD
10508
10509 -- Note: this circuit is partially redundant with respect to the circuit
10510 -- in Checks.Apply_Arithmetic_Overflow_Check, but we catch more cases in
10511 -- the processing here. Also we still need the Checks circuit, since we
10512 -- have to be sure not to generate junk overflow checks in the first
a90bd866 10513 -- place, since it would be trick to remove them here.
eaa826f8 10514
fdfcc663 10515 if Integer_Promotion_Possible (N) then
eaa826f8 10516
fdfcc663 10517 -- All conditions met, go ahead with transformation
eaa826f8 10518
fdfcc663
AC
10519 declare
10520 Opnd : Node_Id;
10521 L, R : Node_Id;
dfcfdc0a 10522
fdfcc663
AC
10523 begin
10524 R :=
10525 Make_Type_Conversion (Loc,
e4494292 10526 Subtype_Mark => New_Occurrence_Of (Standard_Integer, Loc),
fdfcc663 10527 Expression => Relocate_Node (Right_Opnd (Operand)));
eaa826f8 10528
5f3f175d
AC
10529 Opnd := New_Op_Node (Nkind (Operand), Loc);
10530 Set_Right_Opnd (Opnd, R);
eaa826f8 10531
5f3f175d 10532 if Nkind (Operand) in N_Binary_Op then
fdfcc663 10533 L :=
eaa826f8 10534 Make_Type_Conversion (Loc,
e4494292 10535 Subtype_Mark => New_Occurrence_Of (Standard_Integer, Loc),
fdfcc663
AC
10536 Expression => Relocate_Node (Left_Opnd (Operand)));
10537
5f3f175d
AC
10538 Set_Left_Opnd (Opnd, L);
10539 end if;
eaa826f8 10540
5f3f175d
AC
10541 Rewrite (N,
10542 Make_Type_Conversion (Loc,
10543 Subtype_Mark => Relocate_Node (Subtype_Mark (N)),
10544 Expression => Opnd));
dfcfdc0a 10545
5f3f175d 10546 Analyze_And_Resolve (N, Target_Type);
e606088a 10547 goto Done;
fdfcc663
AC
10548 end;
10549 end if;
eaa826f8 10550
f82944b7
JM
10551 -- Do validity check if validity checking operands
10552
533369aa 10553 if Validity_Checks_On and Validity_Check_Operands then
f82944b7
JM
10554 Ensure_Valid (Operand);
10555 end if;
10556
70482933
RK
10557 -- Special case of converting from non-standard boolean type
10558
10559 if Is_Boolean_Type (Operand_Type)
10560 and then (Nonzero_Is_True (Operand_Type))
10561 then
10562 Adjust_Condition (Operand);
10563 Set_Etype (Operand, Standard_Boolean);
10564 Operand_Type := Standard_Boolean;
10565 end if;
10566
10567 -- Case of converting to an access type
10568
10569 if Is_Access_Type (Target_Type) then
10570
d766cee3
RD
10571 -- Apply an accessibility check when the conversion operand is an
10572 -- access parameter (or a renaming thereof), unless conversion was
e84e11ba
GD
10573 -- expanded from an Unchecked_ or Unrestricted_Access attribute.
10574 -- Note that other checks may still need to be applied below (such
10575 -- as tagged type checks).
70482933
RK
10576
10577 if Is_Entity_Name (Operand)
d15f9422 10578 and then Has_Extra_Accessibility (Entity (Operand))
70482933 10579 and then Ekind (Etype (Operand)) = E_Anonymous_Access_Type
d766cee3
RD
10580 and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
10581 or else Attribute_Name (Original_Node (N)) = Name_Access)
70482933 10582 then
e84e11ba
GD
10583 Apply_Accessibility_Check
10584 (Operand, Target_Type, Insert_Node => Operand);
70482933 10585
e84e11ba 10586 -- If the level of the operand type is statically deeper than the
685094bf
RD
10587 -- level of the target type, then force Program_Error. Note that this
10588 -- can only occur for cases where the attribute is within the body of
6c56d9b8
AC
10589 -- an instantiation, otherwise the conversion will already have been
10590 -- rejected as illegal.
10591
10592 -- Note: warnings are issued by the analyzer for the instance cases
70482933
RK
10593
10594 elsif In_Instance_Body
6c56d9b8
AC
10595
10596 -- The case where the target type is an anonymous access type of
10597 -- a discriminant is excluded, because the level of such a type
10598 -- depends on the context and currently the level returned for such
10599 -- types is zero, resulting in warnings about about check failures
10600 -- in certain legal cases involving class-wide interfaces as the
10601 -- designated type (some cases, such as return statements, are
10602 -- checked at run time, but not clear if these are handled right
10603 -- in general, see 3.10.2(12/2-12.5/3) ???).
10604
ad5edba5
AC
10605 and then
10606 not (Ekind (Target_Type) = E_Anonymous_Access_Type
10607 and then Present (Associated_Node_For_Itype (Target_Type))
10608 and then Nkind (Associated_Node_For_Itype (Target_Type)) =
10609 N_Discriminant_Specification)
10610 and then
10611 Type_Access_Level (Operand_Type) > Type_Access_Level (Target_Type)
70482933 10612 then
426908f8 10613 Raise_Accessibility_Error;
91669e7e 10614 goto Done;
70482933 10615
685094bf
RD
10616 -- When the operand is a selected access discriminant the check needs
10617 -- to be made against the level of the object denoted by the prefix
10618 -- of the selected name. Force Program_Error for this case as well
10619 -- (this accessibility violation can only happen if within the body
10620 -- of an instantiation).
70482933
RK
10621
10622 elsif In_Instance_Body
10623 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
10624 and then Nkind (Operand) = N_Selected_Component
10625 and then Object_Access_Level (Operand) >
10626 Type_Access_Level (Target_Type)
10627 then
426908f8 10628 Raise_Accessibility_Error;
e606088a 10629 goto Done;
70482933
RK
10630 end if;
10631 end if;
10632
10633 -- Case of conversions of tagged types and access to tagged types
10634
685094bf
RD
10635 -- When needed, that is to say when the expression is class-wide, Add
10636 -- runtime a tag check for (strict) downward conversion by using the
10637 -- membership test, generating:
70482933
RK
10638
10639 -- [constraint_error when Operand not in Target_Type'Class]
10640
10641 -- or in the access type case
10642
10643 -- [constraint_error
10644 -- when Operand /= null
10645 -- and then Operand.all not in
10646 -- Designated_Type (Target_Type)'Class]
10647
10648 if (Is_Access_Type (Target_Type)
10649 and then Is_Tagged_Type (Designated_Type (Target_Type)))
10650 or else Is_Tagged_Type (Target_Type)
10651 then
685094bf
RD
10652 -- Do not do any expansion in the access type case if the parent is a
10653 -- renaming, since this is an error situation which will be caught by
10654 -- Sem_Ch8, and the expansion can interfere with this error check.
70482933 10655
e7e4d230 10656 if Is_Access_Type (Target_Type) and then Is_Renamed_Object (N) then
e606088a 10657 goto Done;
70482933
RK
10658 end if;
10659
0669bebe 10660 -- Otherwise, proceed with processing tagged conversion
70482933 10661
e7e4d230 10662 Tagged_Conversion : declare
8cea7b64
HK
10663 Actual_Op_Typ : Entity_Id;
10664 Actual_Targ_Typ : Entity_Id;
10665 Make_Conversion : Boolean := False;
10666 Root_Op_Typ : Entity_Id;
70482933 10667
8cea7b64
HK
10668 procedure Make_Tag_Check (Targ_Typ : Entity_Id);
10669 -- Create a membership check to test whether Operand is a member
10670 -- of Targ_Typ. If the original Target_Type is an access, include
10671 -- a test for null value. The check is inserted at N.
10672
10673 --------------------
10674 -- Make_Tag_Check --
10675 --------------------
10676
10677 procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
10678 Cond : Node_Id;
10679
10680 begin
10681 -- Generate:
10682 -- [Constraint_Error
10683 -- when Operand /= null
10684 -- and then Operand.all not in Targ_Typ]
10685
10686 if Is_Access_Type (Target_Type) then
10687 Cond :=
10688 Make_And_Then (Loc,
10689 Left_Opnd =>
10690 Make_Op_Ne (Loc,
10691 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
10692 Right_Opnd => Make_Null (Loc)),
10693
10694 Right_Opnd =>
10695 Make_Not_In (Loc,
10696 Left_Opnd =>
10697 Make_Explicit_Dereference (Loc,
10698 Prefix => Duplicate_Subexpr_No_Checks (Operand)),
e4494292 10699 Right_Opnd => New_Occurrence_Of (Targ_Typ, Loc)));
8cea7b64
HK
10700
10701 -- Generate:
10702 -- [Constraint_Error when Operand not in Targ_Typ]
10703
10704 else
10705 Cond :=
10706 Make_Not_In (Loc,
10707 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
e4494292 10708 Right_Opnd => New_Occurrence_Of (Targ_Typ, Loc));
8cea7b64
HK
10709 end if;
10710
10711 Insert_Action (N,
10712 Make_Raise_Constraint_Error (Loc,
10713 Condition => Cond,
10714 Reason => CE_Tag_Check_Failed));
10715 end Make_Tag_Check;
10716
e7e4d230 10717 -- Start of processing for Tagged_Conversion
70482933
RK
10718
10719 begin
9732e886 10720 -- Handle entities from the limited view
852dba80 10721
9732e886 10722 if Is_Access_Type (Operand_Type) then
852dba80
AC
10723 Actual_Op_Typ :=
10724 Available_View (Designated_Type (Operand_Type));
9732e886
JM
10725 else
10726 Actual_Op_Typ := Operand_Type;
10727 end if;
10728
10729 if Is_Access_Type (Target_Type) then
852dba80
AC
10730 Actual_Targ_Typ :=
10731 Available_View (Designated_Type (Target_Type));
70482933 10732 else
8cea7b64 10733 Actual_Targ_Typ := Target_Type;
70482933
RK
10734 end if;
10735
8cea7b64
HK
10736 Root_Op_Typ := Root_Type (Actual_Op_Typ);
10737
20b5d666
JM
10738 -- Ada 2005 (AI-251): Handle interface type conversion
10739
3cb9a885 10740 if Is_Interface (Actual_Op_Typ)
58b81ab0
AC
10741 or else
10742 Is_Interface (Actual_Targ_Typ)
3cb9a885 10743 then
f6f4d8d4 10744 Expand_Interface_Conversion (N);
e606088a 10745 goto Done;
20b5d666
JM
10746 end if;
10747
8cea7b64 10748 if not Tag_Checks_Suppressed (Actual_Targ_Typ) then
70482933 10749
8cea7b64
HK
10750 -- Create a runtime tag check for a downward class-wide type
10751 -- conversion.
70482933 10752
8cea7b64 10753 if Is_Class_Wide_Type (Actual_Op_Typ)
852dba80 10754 and then Actual_Op_Typ /= Actual_Targ_Typ
8cea7b64 10755 and then Root_Op_Typ /= Actual_Targ_Typ
4ac2477e
JM
10756 and then Is_Ancestor (Root_Op_Typ, Actual_Targ_Typ,
10757 Use_Full_View => True)
8cea7b64
HK
10758 then
10759 Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
10760 Make_Conversion := True;
10761 end if;
70482933 10762
8cea7b64
HK
10763 -- AI05-0073: If the result subtype of the function is defined
10764 -- by an access_definition designating a specific tagged type
10765 -- T, a check is made that the result value is null or the tag
10766 -- of the object designated by the result value identifies T.
10767 -- Constraint_Error is raised if this check fails.
70482933 10768
92a7cd46 10769 if Nkind (Parent (N)) = N_Simple_Return_Statement then
8cea7b64 10770 declare
e886436a 10771 Func : Entity_Id;
8cea7b64
HK
10772 Func_Typ : Entity_Id;
10773
10774 begin
e886436a 10775 -- Climb scope stack looking for the enclosing function
8cea7b64 10776
e886436a 10777 Func := Current_Scope;
8cea7b64
HK
10778 while Present (Func)
10779 and then Ekind (Func) /= E_Function
10780 loop
10781 Func := Scope (Func);
10782 end loop;
10783
10784 -- The function's return subtype must be defined using
10785 -- an access definition.
10786
10787 if Nkind (Result_Definition (Parent (Func))) =
10788 N_Access_Definition
10789 then
10790 Func_Typ := Directly_Designated_Type (Etype (Func));
10791
10792 -- The return subtype denotes a specific tagged type,
10793 -- in other words, a non class-wide type.
10794
10795 if Is_Tagged_Type (Func_Typ)
10796 and then not Is_Class_Wide_Type (Func_Typ)
10797 then
10798 Make_Tag_Check (Actual_Targ_Typ);
10799 Make_Conversion := True;
10800 end if;
10801 end if;
10802 end;
70482933
RK
10803 end if;
10804
8cea7b64
HK
10805 -- We have generated a tag check for either a class-wide type
10806 -- conversion or for AI05-0073.
70482933 10807
8cea7b64
HK
10808 if Make_Conversion then
10809 declare
10810 Conv : Node_Id;
10811 begin
10812 Conv :=
10813 Make_Unchecked_Type_Conversion (Loc,
10814 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
10815 Expression => Relocate_Node (Expression (N)));
10816 Rewrite (N, Conv);
10817 Analyze_And_Resolve (N, Target_Type);
10818 end;
10819 end if;
70482933 10820 end if;
e7e4d230 10821 end Tagged_Conversion;
70482933
RK
10822
10823 -- Case of other access type conversions
10824
10825 elsif Is_Access_Type (Target_Type) then
10826 Apply_Constraint_Check (Operand, Target_Type);
10827
10828 -- Case of conversions from a fixed-point type
10829
685094bf
RD
10830 -- These conversions require special expansion and processing, found in
10831 -- the Exp_Fixd package. We ignore cases where Conversion_OK is set,
10832 -- since from a semantic point of view, these are simple integer
70482933
RK
10833 -- conversions, which do not need further processing.
10834
10835 elsif Is_Fixed_Point_Type (Operand_Type)
10836 and then not Conversion_OK (N)
10837 then
10838 -- We should never see universal fixed at this case, since the
10839 -- expansion of the constituent divide or multiply should have
10840 -- eliminated the explicit mention of universal fixed.
10841
10842 pragma Assert (Operand_Type /= Universal_Fixed);
10843
685094bf
RD
10844 -- Check for special case of the conversion to universal real that
10845 -- occurs as a result of the use of a round attribute. In this case,
10846 -- the real type for the conversion is taken from the target type of
10847 -- the Round attribute and the result must be marked as rounded.
70482933
RK
10848
10849 if Target_Type = Universal_Real
10850 and then Nkind (Parent (N)) = N_Attribute_Reference
10851 and then Attribute_Name (Parent (N)) = Name_Round
10852 then
10853 Set_Rounded_Result (N);
10854 Set_Etype (N, Etype (Parent (N)));
10855 end if;
10856
10857 -- Otherwise do correct fixed-conversion, but skip these if the
e7e4d230
AC
10858 -- Conversion_OK flag is set, because from a semantic point of view
10859 -- these are simple integer conversions needing no further processing
10860 -- (the backend will simply treat them as integers).
70482933
RK
10861
10862 if not Conversion_OK (N) then
10863 if Is_Fixed_Point_Type (Etype (N)) then
10864 Expand_Convert_Fixed_To_Fixed (N);
10865 Real_Range_Check;
10866
10867 elsif Is_Integer_Type (Etype (N)) then
10868 Expand_Convert_Fixed_To_Integer (N);
10869
10870 else
10871 pragma Assert (Is_Floating_Point_Type (Etype (N)));
10872 Expand_Convert_Fixed_To_Float (N);
10873 Real_Range_Check;
10874 end if;
10875 end if;
10876
10877 -- Case of conversions to a fixed-point type
10878
685094bf
RD
10879 -- These conversions require special expansion and processing, found in
10880 -- the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
10881 -- since from a semantic point of view, these are simple integer
10882 -- conversions, which do not need further processing.
70482933
RK
10883
10884 elsif Is_Fixed_Point_Type (Target_Type)
10885 and then not Conversion_OK (N)
10886 then
10887 if Is_Integer_Type (Operand_Type) then
10888 Expand_Convert_Integer_To_Fixed (N);
10889 Real_Range_Check;
10890 else
10891 pragma Assert (Is_Floating_Point_Type (Operand_Type));
10892 Expand_Convert_Float_To_Fixed (N);
10893 Real_Range_Check;
10894 end if;
10895
10896 -- Case of float-to-integer conversions
10897
10898 -- We also handle float-to-fixed conversions with Conversion_OK set
10899 -- since semantically the fixed-point target is treated as though it
10900 -- were an integer in such cases.
10901
10902 elsif Is_Floating_Point_Type (Operand_Type)
10903 and then
10904 (Is_Integer_Type (Target_Type)
10905 or else
10906 (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
10907 then
70482933
RK
10908 -- One more check here, gcc is still not able to do conversions of
10909 -- this type with proper overflow checking, and so gigi is doing an
10910 -- approximation of what is required by doing floating-point compares
10911 -- with the end-point. But that can lose precision in some cases, and
f02b8bb8 10912 -- give a wrong result. Converting the operand to Universal_Real is
70482933 10913 -- helpful, but still does not catch all cases with 64-bit integers
e7e4d230 10914 -- on targets with only 64-bit floats.
0669bebe
GB
10915
10916 -- The above comment seems obsoleted by Apply_Float_Conversion_Check
10917 -- Can this code be removed ???
70482933 10918
fbf5a39b
AC
10919 if Do_Range_Check (Operand) then
10920 Rewrite (Operand,
70482933
RK
10921 Make_Type_Conversion (Loc,
10922 Subtype_Mark =>
f02b8bb8 10923 New_Occurrence_Of (Universal_Real, Loc),
70482933 10924 Expression =>
fbf5a39b 10925 Relocate_Node (Operand)));
70482933 10926
f02b8bb8 10927 Set_Etype (Operand, Universal_Real);
fbf5a39b
AC
10928 Enable_Range_Check (Operand);
10929 Set_Do_Range_Check (Expression (Operand), False);
70482933
RK
10930 end if;
10931
10932 -- Case of array conversions
10933
685094bf
RD
10934 -- Expansion of array conversions, add required length/range checks but
10935 -- only do this if there is no change of representation. For handling of
10936 -- this case, see Handle_Changed_Representation.
70482933
RK
10937
10938 elsif Is_Array_Type (Target_Type) then
70482933
RK
10939 if Is_Constrained (Target_Type) then
10940 Apply_Length_Check (Operand, Target_Type);
10941 else
10942 Apply_Range_Check (Operand, Target_Type);
10943 end if;
10944
10945 Handle_Changed_Representation;
10946
10947 -- Case of conversions of discriminated types
10948
685094bf
RD
10949 -- Add required discriminant checks if target is constrained. Again this
10950 -- change is skipped if we have a change of representation.
70482933
RK
10951
10952 elsif Has_Discriminants (Target_Type)
10953 and then Is_Constrained (Target_Type)
10954 then
10955 Apply_Discriminant_Check (Operand, Target_Type);
10956 Handle_Changed_Representation;
10957
10958 -- Case of all other record conversions. The only processing required
10959 -- is to check for a change of representation requiring the special
10960 -- assignment processing.
10961
10962 elsif Is_Record_Type (Target_Type) then
5d09245e
AC
10963
10964 -- Ada 2005 (AI-216): Program_Error is raised when converting from
685094bf
RD
10965 -- a derived Unchecked_Union type to an unconstrained type that is
10966 -- not Unchecked_Union if the operand lacks inferable discriminants.
5d09245e
AC
10967
10968 if Is_Derived_Type (Operand_Type)
10969 and then Is_Unchecked_Union (Base_Type (Operand_Type))
10970 and then not Is_Constrained (Target_Type)
10971 and then not Is_Unchecked_Union (Base_Type (Target_Type))
10972 and then not Has_Inferable_Discriminants (Operand)
10973 then
685094bf 10974 -- To prevent Gigi from generating illegal code, we generate a
5d09245e 10975 -- Program_Error node, but we give it the target type of the
6cb3037c 10976 -- conversion (is this requirement documented somewhere ???)
5d09245e
AC
10977
10978 declare
10979 PE : constant Node_Id := Make_Raise_Program_Error (Loc,
10980 Reason => PE_Unchecked_Union_Restriction);
10981
10982 begin
10983 Set_Etype (PE, Target_Type);
10984 Rewrite (N, PE);
10985
10986 end;
10987 else
10988 Handle_Changed_Representation;
10989 end if;
70482933
RK
10990
10991 -- Case of conversions of enumeration types
10992
10993 elsif Is_Enumeration_Type (Target_Type) then
10994
10995 -- Special processing is required if there is a change of
e7e4d230 10996 -- representation (from enumeration representation clauses).
70482933
RK
10997
10998 if not Same_Representation (Target_Type, Operand_Type) then
10999
11000 -- Convert: x(y) to x'val (ytyp'val (y))
11001
11002 Rewrite (N,
1c66c4f5
AC
11003 Make_Attribute_Reference (Loc,
11004 Prefix => New_Occurrence_Of (Target_Type, Loc),
11005 Attribute_Name => Name_Val,
11006 Expressions => New_List (
11007 Make_Attribute_Reference (Loc,
11008 Prefix => New_Occurrence_Of (Operand_Type, Loc),
11009 Attribute_Name => Name_Pos,
11010 Expressions => New_List (Operand)))));
70482933
RK
11011
11012 Analyze_And_Resolve (N, Target_Type);
11013 end if;
11014
11015 -- Case of conversions to floating-point
11016
11017 elsif Is_Floating_Point_Type (Target_Type) then
11018 Real_Range_Check;
70482933
RK
11019 end if;
11020
685094bf 11021 -- At this stage, either the conversion node has been transformed into
e7e4d230
AC
11022 -- some other equivalent expression, or left as a conversion that can be
11023 -- handled by Gigi, in the following cases:
70482933
RK
11024
11025 -- Conversions with no change of representation or type
11026
685094bf
RD
11027 -- Numeric conversions involving integer, floating- and fixed-point
11028 -- values. Fixed-point values are allowed only if Conversion_OK is
11029 -- set, i.e. if the fixed-point values are to be treated as integers.
70482933 11030
5e1c00fa
RD
11031 -- No other conversions should be passed to Gigi
11032
11033 -- Check: are these rules stated in sinfo??? if so, why restate here???
70482933 11034
685094bf
RD
11035 -- The only remaining step is to generate a range check if we still have
11036 -- a type conversion at this stage and Do_Range_Check is set. For now we
f5655e4a
AC
11037 -- do this only for conversions of discrete types and for float-to-float
11038 -- conversions.
fbf5a39b 11039
7b536495 11040 if Nkind (N) = N_Type_Conversion then
fbf5a39b 11041
f5655e4a
AC
11042 -- For now we only support floating-point cases where both source
11043 -- and target are floating-point types. Conversions where the source
11044 -- and target involve integer or fixed-point types are still TBD,
11045 -- though not clear whether those can even happen at this point, due
11046 -- to transformations above. ???
fbf5a39b 11047
7b536495 11048 if Is_Floating_Point_Type (Etype (N))
f5655e4a 11049 and then Is_Floating_Point_Type (Etype (Expression (N)))
7b536495
AC
11050 then
11051 if Do_Range_Check (Expression (N))
11052 and then Is_Floating_Point_Type (Target_Type)
11053 then
11054 Generate_Range_Check
11055 (Expression (N), Target_Type, CE_Range_Check_Failed);
11056 end if;
fbf5a39b 11057
f5655e4a
AC
11058 -- Discrete-to-discrete conversions
11059
7b536495
AC
11060 elsif Is_Discrete_Type (Etype (N)) then
11061 declare
11062 Expr : constant Node_Id := Expression (N);
11063 Ftyp : Entity_Id;
11064 Ityp : Entity_Id;
fbf5a39b 11065
7b536495
AC
11066 begin
11067 if Do_Range_Check (Expr)
11068 and then Is_Discrete_Type (Etype (Expr))
fbf5a39b 11069 then
7b536495 11070 Set_Do_Range_Check (Expr, False);
fbf5a39b 11071
7b536495
AC
11072 -- Before we do a range check, we have to deal with treating
11073 -- a fixed-point operand as an integer. The way we do this
11074 -- is simply to do an unchecked conversion to an appropriate
11075 -- integer type large enough to hold the result.
fbf5a39b 11076
7b536495
AC
11077 -- This code is not active yet, because we are only dealing
11078 -- with discrete types so far ???
fbf5a39b 11079
7b536495
AC
11080 if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
11081 and then Treat_Fixed_As_Integer (Expr)
11082 then
11083 Ftyp := Base_Type (Etype (Expr));
fbf5a39b 11084
7b536495
AC
11085 if Esize (Ftyp) >= Esize (Standard_Integer) then
11086 Ityp := Standard_Long_Long_Integer;
11087 else
11088 Ityp := Standard_Integer;
11089 end if;
edab6088 11090
7b536495
AC
11091 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
11092 end if;
11093
11094 -- Reset overflow flag, since the range check will include
11095 -- dealing with possible overflow, and generate the check.
11096 -- If Address is either a source type or target type,
11097 -- suppress range check to avoid typing anomalies when
11098 -- it is a visible integer type.
11099
11100 Set_Do_Overflow_Check (N, False);
11101
11102 if not Is_Descendent_Of_Address (Etype (Expr))
11103 and then not Is_Descendent_Of_Address (Target_Type)
11104 then
11105 Generate_Range_Check
11106 (Expr, Target_Type, CE_Range_Check_Failed);
11107 end if;
8a36a0cc 11108 end if;
7b536495
AC
11109 end;
11110 end if;
fbf5a39b 11111 end if;
f02b8bb8 11112
e606088a
AC
11113 -- Here at end of processing
11114
48f91b44
RD
11115 <<Done>>
11116 -- Apply predicate check if required. Note that we can't just call
11117 -- Apply_Predicate_Check here, because the type looks right after
11118 -- the conversion and it would omit the check. The Comes_From_Source
11119 -- guard is necessary to prevent infinite recursions when we generate
11120 -- internal conversions for the purpose of checking predicates.
11121
11122 if Present (Predicate_Function (Target_Type))
11123 and then Target_Type /= Operand_Type
11124 and then Comes_From_Source (N)
11125 then
00332244
AC
11126 declare
11127 New_Expr : constant Node_Id := Duplicate_Subexpr (N);
11128
11129 begin
11130 -- Avoid infinite recursion on the subsequent expansion of
11131 -- of the copy of the original type conversion.
11132
11133 Set_Comes_From_Source (New_Expr, False);
11134 Insert_Action (N, Make_Predicate_Check (Target_Type, New_Expr));
11135 end;
48f91b44 11136 end if;
70482933
RK
11137 end Expand_N_Type_Conversion;
11138
11139 -----------------------------------
11140 -- Expand_N_Unchecked_Expression --
11141 -----------------------------------
11142
e7e4d230 11143 -- Remove the unchecked expression node from the tree. Its job was simply
70482933
RK
11144 -- to make sure that its constituent expression was handled with checks
11145 -- off, and now that that is done, we can remove it from the tree, and
e7e4d230 11146 -- indeed must, since Gigi does not expect to see these nodes.
70482933
RK
11147
11148 procedure Expand_N_Unchecked_Expression (N : Node_Id) is
11149 Exp : constant Node_Id := Expression (N);
70482933 11150 begin
e7e4d230 11151 Set_Assignment_OK (Exp, Assignment_OK (N) or else Assignment_OK (Exp));
70482933
RK
11152 Rewrite (N, Exp);
11153 end Expand_N_Unchecked_Expression;
11154
11155 ----------------------------------------
11156 -- Expand_N_Unchecked_Type_Conversion --
11157 ----------------------------------------
11158
685094bf
RD
11159 -- If this cannot be handled by Gigi and we haven't already made a
11160 -- temporary for it, do it now.
70482933
RK
11161
11162 procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
11163 Target_Type : constant Entity_Id := Etype (N);
11164 Operand : constant Node_Id := Expression (N);
11165 Operand_Type : constant Entity_Id := Etype (Operand);
11166
11167 begin
7b00e31d 11168 -- Nothing at all to do if conversion is to the identical type so remove
76efd572 11169 -- the conversion completely, it is useless, except that it may carry
e7e4d230 11170 -- an Assignment_OK indication which must be propagated to the operand.
7b00e31d
AC
11171
11172 if Operand_Type = Target_Type then
13d923cc 11173
e7e4d230
AC
11174 -- Code duplicates Expand_N_Unchecked_Expression above, factor???
11175
7b00e31d
AC
11176 if Assignment_OK (N) then
11177 Set_Assignment_OK (Operand);
11178 end if;
11179
11180 Rewrite (N, Relocate_Node (Operand));
11181 return;
11182 end if;
11183
70482933
RK
11184 -- If we have a conversion of a compile time known value to a target
11185 -- type and the value is in range of the target type, then we can simply
11186 -- replace the construct by an integer literal of the correct type. We
11187 -- only apply this to integer types being converted. Possibly it may
11188 -- apply in other cases, but it is too much trouble to worry about.
11189
11190 -- Note that we do not do this transformation if the Kill_Range_Check
11191 -- flag is set, since then the value may be outside the expected range.
11192 -- This happens in the Normalize_Scalars case.
11193
20b5d666
JM
11194 -- We also skip this if either the target or operand type is biased
11195 -- because in this case, the unchecked conversion is supposed to
11196 -- preserve the bit pattern, not the integer value.
11197
70482933 11198 if Is_Integer_Type (Target_Type)
20b5d666 11199 and then not Has_Biased_Representation (Target_Type)
70482933 11200 and then Is_Integer_Type (Operand_Type)
20b5d666 11201 and then not Has_Biased_Representation (Operand_Type)
70482933
RK
11202 and then Compile_Time_Known_Value (Operand)
11203 and then not Kill_Range_Check (N)
11204 then
11205 declare
11206 Val : constant Uint := Expr_Value (Operand);
11207
11208 begin
11209 if Compile_Time_Known_Value (Type_Low_Bound (Target_Type))
11210 and then
11211 Compile_Time_Known_Value (Type_High_Bound (Target_Type))
11212 and then
11213 Val >= Expr_Value (Type_Low_Bound (Target_Type))
11214 and then
11215 Val <= Expr_Value (Type_High_Bound (Target_Type))
11216 then
11217 Rewrite (N, Make_Integer_Literal (Sloc (N), Val));
8a36a0cc 11218
685094bf
RD
11219 -- If Address is the target type, just set the type to avoid a
11220 -- spurious type error on the literal when Address is a visible
11221 -- integer type.
8a36a0cc
AC
11222
11223 if Is_Descendent_Of_Address (Target_Type) then
11224 Set_Etype (N, Target_Type);
11225 else
11226 Analyze_And_Resolve (N, Target_Type);
11227 end if;
11228
70482933
RK
11229 return;
11230 end if;
11231 end;
11232 end if;
11233
11234 -- Nothing to do if conversion is safe
11235
11236 if Safe_Unchecked_Type_Conversion (N) then
11237 return;
11238 end if;
11239
11240 -- Otherwise force evaluation unless Assignment_OK flag is set (this
324ac540 11241 -- flag indicates ??? More comments needed here)
70482933
RK
11242
11243 if Assignment_OK (N) then
11244 null;
11245 else
11246 Force_Evaluation (N);
11247 end if;
11248 end Expand_N_Unchecked_Type_Conversion;
11249
11250 ----------------------------
11251 -- Expand_Record_Equality --
11252 ----------------------------
11253
11254 -- For non-variant records, Equality is expanded when needed into:
11255
11256 -- and then Lhs.Discr1 = Rhs.Discr1
11257 -- and then ...
11258 -- and then Lhs.Discrn = Rhs.Discrn
11259 -- and then Lhs.Cmp1 = Rhs.Cmp1
11260 -- and then ...
11261 -- and then Lhs.Cmpn = Rhs.Cmpn
11262
11263 -- The expression is folded by the back-end for adjacent fields. This
11264 -- function is called for tagged record in only one occasion: for imple-
11265 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
11266 -- otherwise the primitive "=" is used directly.
11267
11268 function Expand_Record_Equality
11269 (Nod : Node_Id;
11270 Typ : Entity_Id;
11271 Lhs : Node_Id;
11272 Rhs : Node_Id;
2e071734 11273 Bodies : List_Id) return Node_Id
70482933
RK
11274 is
11275 Loc : constant Source_Ptr := Sloc (Nod);
11276
0ab80019
AC
11277 Result : Node_Id;
11278 C : Entity_Id;
11279
11280 First_Time : Boolean := True;
11281
6b670dcf
AC
11282 function Element_To_Compare (C : Entity_Id) return Entity_Id;
11283 -- Return the next discriminant or component to compare, starting with
11284 -- C, skipping inherited components.
0ab80019 11285
6b670dcf
AC
11286 ------------------------
11287 -- Element_To_Compare --
11288 ------------------------
70482933 11289
6b670dcf
AC
11290 function Element_To_Compare (C : Entity_Id) return Entity_Id is
11291 Comp : Entity_Id;
28270211 11292
70482933 11293 begin
6b670dcf 11294 Comp := C;
6b670dcf
AC
11295 loop
11296 -- Exit loop when the next element to be compared is found, or
11297 -- there is no more such element.
70482933 11298
6b670dcf 11299 exit when No (Comp);
8190087e 11300
6b670dcf
AC
11301 exit when Ekind_In (Comp, E_Discriminant, E_Component)
11302 and then not (
70482933 11303
6b670dcf 11304 -- Skip inherited components
70482933 11305
6b670dcf
AC
11306 -- Note: for a tagged type, we always generate the "=" primitive
11307 -- for the base type (not on the first subtype), so the test for
11308 -- Comp /= Original_Record_Component (Comp) is True for
11309 -- inherited components only.
24558db8 11310
6b670dcf 11311 (Is_Tagged_Type (Typ)
28270211 11312 and then Comp /= Original_Record_Component (Comp))
24558db8 11313
6b670dcf 11314 -- Skip _Tag
26bff3d9 11315
6b670dcf
AC
11316 or else Chars (Comp) = Name_uTag
11317
11318 -- The .NET/JVM version of type Root_Controlled contains two
11319 -- fields which should not be considered part of the object. To
11320 -- achieve proper equiality between two controlled objects on
11321 -- .NET/JVM, skip _Parent whenever it has type Root_Controlled.
11322
11323 or else (Chars (Comp) = Name_uParent
28270211
AC
11324 and then VM_Target /= No_VM
11325 and then Etype (Comp) = RTE (RE_Root_Controlled))
6b670dcf
AC
11326
11327 -- Skip interface elements (secondary tags???)
11328
11329 or else Is_Interface (Etype (Comp)));
11330
11331 Next_Entity (Comp);
11332 end loop;
11333
11334 return Comp;
11335 end Element_To_Compare;
70482933 11336
70482933
RK
11337 -- Start of processing for Expand_Record_Equality
11338
11339 begin
70482933
RK
11340 -- Generates the following code: (assuming that Typ has one Discr and
11341 -- component C2 is also a record)
11342
11343 -- True
11344 -- and then Lhs.Discr1 = Rhs.Discr1
11345 -- and then Lhs.C1 = Rhs.C1
11346 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
11347 -- and then ...
11348 -- and then Lhs.Cmpn = Rhs.Cmpn
11349
e4494292 11350 Result := New_Occurrence_Of (Standard_True, Loc);
6b670dcf 11351 C := Element_To_Compare (First_Entity (Typ));
70482933 11352 while Present (C) loop
70482933
RK
11353 declare
11354 New_Lhs : Node_Id;
11355 New_Rhs : Node_Id;
8aceda64 11356 Check : Node_Id;
70482933
RK
11357
11358 begin
11359 if First_Time then
11360 First_Time := False;
11361 New_Lhs := Lhs;
11362 New_Rhs := Rhs;
70482933
RK
11363 else
11364 New_Lhs := New_Copy_Tree (Lhs);
11365 New_Rhs := New_Copy_Tree (Rhs);
11366 end if;
11367
8aceda64
AC
11368 Check :=
11369 Expand_Composite_Equality (Nod, Etype (C),
11370 Lhs =>
11371 Make_Selected_Component (Loc,
8d80ff64 11372 Prefix => New_Lhs,
e4494292 11373 Selector_Name => New_Occurrence_Of (C, Loc)),
8aceda64
AC
11374 Rhs =>
11375 Make_Selected_Component (Loc,
8d80ff64 11376 Prefix => New_Rhs,
e4494292 11377 Selector_Name => New_Occurrence_Of (C, Loc)),
8aceda64
AC
11378 Bodies => Bodies);
11379
11380 -- If some (sub)component is an unchecked_union, the whole
11381 -- operation will raise program error.
11382
11383 if Nkind (Check) = N_Raise_Program_Error then
11384 Result := Check;
11385 Set_Etype (Result, Standard_Boolean);
11386 exit;
11387 else
11388 Result :=
11389 Make_And_Then (Loc,
11390 Left_Opnd => Result,
11391 Right_Opnd => Check);
11392 end if;
70482933
RK
11393 end;
11394
6b670dcf 11395 C := Element_To_Compare (Next_Entity (C));
70482933
RK
11396 end loop;
11397
11398 return Result;
11399 end Expand_Record_Equality;
11400
a3068ca6
AC
11401 ---------------------------
11402 -- Expand_Set_Membership --
11403 ---------------------------
11404
11405 procedure Expand_Set_Membership (N : Node_Id) is
11406 Lop : constant Node_Id := Left_Opnd (N);
11407 Alt : Node_Id;
11408 Res : Node_Id;
11409
11410 function Make_Cond (Alt : Node_Id) return Node_Id;
11411 -- If the alternative is a subtype mark, create a simple membership
11412 -- test. Otherwise create an equality test for it.
11413
11414 ---------------
11415 -- Make_Cond --
11416 ---------------
11417
11418 function Make_Cond (Alt : Node_Id) return Node_Id is
11419 Cond : Node_Id;
11420 L : constant Node_Id := New_Copy (Lop);
11421 R : constant Node_Id := Relocate_Node (Alt);
11422
11423 begin
11424 if (Is_Entity_Name (Alt) and then Is_Type (Entity (Alt)))
11425 or else Nkind (Alt) = N_Range
11426 then
11427 Cond :=
11428 Make_In (Sloc (Alt),
11429 Left_Opnd => L,
11430 Right_Opnd => R);
11431 else
11432 Cond :=
11433 Make_Op_Eq (Sloc (Alt),
11434 Left_Opnd => L,
11435 Right_Opnd => R);
11436 end if;
11437
11438 return Cond;
11439 end Make_Cond;
11440
11441 -- Start of processing for Expand_Set_Membership
11442
11443 begin
11444 Remove_Side_Effects (Lop);
11445
11446 Alt := Last (Alternatives (N));
11447 Res := Make_Cond (Alt);
11448
11449 Prev (Alt);
11450 while Present (Alt) loop
11451 Res :=
11452 Make_Or_Else (Sloc (Alt),
11453 Left_Opnd => Make_Cond (Alt),
11454 Right_Opnd => Res);
11455 Prev (Alt);
11456 end loop;
11457
11458 Rewrite (N, Res);
11459 Analyze_And_Resolve (N, Standard_Boolean);
11460 end Expand_Set_Membership;
11461
5875f8d6
AC
11462 -----------------------------------
11463 -- Expand_Short_Circuit_Operator --
11464 -----------------------------------
11465
955871d3
AC
11466 -- Deal with special expansion if actions are present for the right operand
11467 -- and deal with optimizing case of arguments being True or False. We also
11468 -- deal with the special case of non-standard boolean values.
5875f8d6
AC
11469
11470 procedure Expand_Short_Circuit_Operator (N : Node_Id) is
11471 Loc : constant Source_Ptr := Sloc (N);
11472 Typ : constant Entity_Id := Etype (N);
5875f8d6
AC
11473 Left : constant Node_Id := Left_Opnd (N);
11474 Right : constant Node_Id := Right_Opnd (N);
955871d3 11475 LocR : constant Source_Ptr := Sloc (Right);
5875f8d6
AC
11476 Actlist : List_Id;
11477
11478 Shortcut_Value : constant Boolean := Nkind (N) = N_Or_Else;
11479 Shortcut_Ent : constant Entity_Id := Boolean_Literals (Shortcut_Value);
11480 -- If Left = Shortcut_Value then Right need not be evaluated
11481
5875f8d6
AC
11482 begin
11483 -- Deal with non-standard booleans
11484
11485 if Is_Boolean_Type (Typ) then
11486 Adjust_Condition (Left);
11487 Adjust_Condition (Right);
11488 Set_Etype (N, Standard_Boolean);
11489 end if;
11490
11491 -- Check for cases where left argument is known to be True or False
11492
11493 if Compile_Time_Known_Value (Left) then
25adc5fb
AC
11494
11495 -- Mark SCO for left condition as compile time known
11496
11497 if Generate_SCO and then Comes_From_Source (Left) then
11498 Set_SCO_Condition (Left, Expr_Value_E (Left) = Standard_True);
11499 end if;
11500
5875f8d6
AC
11501 -- Rewrite True AND THEN Right / False OR ELSE Right to Right.
11502 -- Any actions associated with Right will be executed unconditionally
11503 -- and can thus be inserted into the tree unconditionally.
11504
11505 if Expr_Value_E (Left) /= Shortcut_Ent then
11506 if Present (Actions (N)) then
11507 Insert_Actions (N, Actions (N));
11508 end if;
11509
11510 Rewrite (N, Right);
11511
11512 -- Rewrite False AND THEN Right / True OR ELSE Right to Left.
11513 -- In this case we can forget the actions associated with Right,
11514 -- since they will never be executed.
11515
11516 else
11517 Kill_Dead_Code (Right);
11518 Kill_Dead_Code (Actions (N));
11519 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
11520 end if;
11521
11522 Adjust_Result_Type (N, Typ);
11523 return;
11524 end if;
11525
955871d3
AC
11526 -- If Actions are present for the right operand, we have to do some
11527 -- special processing. We can't just let these actions filter back into
11528 -- code preceding the short circuit (which is what would have happened
11529 -- if we had not trapped them in the short-circuit form), since they
11530 -- must only be executed if the right operand of the short circuit is
11531 -- executed and not otherwise.
5875f8d6 11532
955871d3
AC
11533 if Present (Actions (N)) then
11534 Actlist := Actions (N);
5875f8d6 11535
0812b84e
AC
11536 -- We now use an Expression_With_Actions node for the right operand
11537 -- of the short-circuit form. Note that this solves the traceability
11538 -- problems for coverage analysis.
5875f8d6 11539
0812b84e 11540 Rewrite (Right,
4b17187f
AC
11541 Make_Expression_With_Actions (LocR,
11542 Expression => Relocate_Node (Right),
11543 Actions => Actlist));
11544
0812b84e
AC
11545 Set_Actions (N, No_List);
11546 Analyze_And_Resolve (Right, Standard_Boolean);
955871d3 11547
5875f8d6
AC
11548 Adjust_Result_Type (N, Typ);
11549 return;
11550 end if;
11551
11552 -- No actions present, check for cases of right argument True/False
11553
11554 if Compile_Time_Known_Value (Right) then
25adc5fb
AC
11555
11556 -- Mark SCO for left condition as compile time known
11557
11558 if Generate_SCO and then Comes_From_Source (Right) then
11559 Set_SCO_Condition (Right, Expr_Value_E (Right) = Standard_True);
11560 end if;
11561
5875f8d6
AC
11562 -- Change (Left and then True), (Left or else False) to Left.
11563 -- Note that we know there are no actions associated with the right
11564 -- operand, since we just checked for this case above.
11565
11566 if Expr_Value_E (Right) /= Shortcut_Ent then
11567 Rewrite (N, Left);
11568
11569 -- Change (Left and then False), (Left or else True) to Right,
11570 -- making sure to preserve any side effects associated with the Left
11571 -- operand.
11572
11573 else
11574 Remove_Side_Effects (Left);
11575 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
11576 end if;
11577 end if;
11578
11579 Adjust_Result_Type (N, Typ);
11580 end Expand_Short_Circuit_Operator;
11581
70482933
RK
11582 -------------------------------------
11583 -- Fixup_Universal_Fixed_Operation --
11584 -------------------------------------
11585
11586 procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
11587 Conv : constant Node_Id := Parent (N);
11588
11589 begin
11590 -- We must have a type conversion immediately above us
11591
11592 pragma Assert (Nkind (Conv) = N_Type_Conversion);
11593
11594 -- Normally the type conversion gives our target type. The exception
11595 -- occurs in the case of the Round attribute, where the conversion
11596 -- will be to universal real, and our real type comes from the Round
11597 -- attribute (as well as an indication that we must round the result)
11598
11599 if Nkind (Parent (Conv)) = N_Attribute_Reference
11600 and then Attribute_Name (Parent (Conv)) = Name_Round
11601 then
11602 Set_Etype (N, Etype (Parent (Conv)));
11603 Set_Rounded_Result (N);
11604
11605 -- Normal case where type comes from conversion above us
11606
11607 else
11608 Set_Etype (N, Etype (Conv));
11609 end if;
11610 end Fixup_Universal_Fixed_Operation;
11611
5d09245e
AC
11612 ---------------------------------
11613 -- Has_Inferable_Discriminants --
11614 ---------------------------------
11615
11616 function Has_Inferable_Discriminants (N : Node_Id) return Boolean is
11617
11618 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean;
11619 -- Determines whether the left-most prefix of a selected component is a
11620 -- formal parameter in a subprogram. Assumes N is a selected component.
11621
11622 --------------------------------
11623 -- Prefix_Is_Formal_Parameter --
11624 --------------------------------
11625
11626 function Prefix_Is_Formal_Parameter (N : Node_Id) return Boolean is
83bb90af 11627 Sel_Comp : Node_Id;
5d09245e
AC
11628
11629 begin
11630 -- Move to the left-most prefix by climbing up the tree
11631
83bb90af 11632 Sel_Comp := N;
5d09245e
AC
11633 while Present (Parent (Sel_Comp))
11634 and then Nkind (Parent (Sel_Comp)) = N_Selected_Component
11635 loop
11636 Sel_Comp := Parent (Sel_Comp);
11637 end loop;
11638
11639 return Ekind (Entity (Prefix (Sel_Comp))) in Formal_Kind;
11640 end Prefix_Is_Formal_Parameter;
11641
11642 -- Start of processing for Has_Inferable_Discriminants
11643
11644 begin
5d09245e
AC
11645 -- For selected components, the subtype of the selector must be a
11646 -- constrained Unchecked_Union. If the component is subject to a
11647 -- per-object constraint, then the enclosing object must have inferable
11648 -- discriminants.
11649
83bb90af 11650 if Nkind (N) = N_Selected_Component then
5d09245e
AC
11651 if Has_Per_Object_Constraint (Entity (Selector_Name (N))) then
11652
11653 -- A small hack. If we have a per-object constrained selected
11654 -- component of a formal parameter, return True since we do not
11655 -- know the actual parameter association yet.
11656
11657 if Prefix_Is_Formal_Parameter (N) then
11658 return True;
5d09245e
AC
11659
11660 -- Otherwise, check the enclosing object and the selector
11661
83bb90af
TQ
11662 else
11663 return Has_Inferable_Discriminants (Prefix (N))
11664 and then Has_Inferable_Discriminants (Selector_Name (N));
11665 end if;
5d09245e
AC
11666
11667 -- The call to Has_Inferable_Discriminants will determine whether
11668 -- the selector has a constrained Unchecked_Union nominal type.
11669
83bb90af
TQ
11670 else
11671 return Has_Inferable_Discriminants (Selector_Name (N));
11672 end if;
5d09245e
AC
11673
11674 -- A qualified expression has inferable discriminants if its subtype
11675 -- mark is a constrained Unchecked_Union subtype.
11676
11677 elsif Nkind (N) = N_Qualified_Expression then
053cf994 11678 return Is_Unchecked_Union (Etype (Subtype_Mark (N)))
5b5b27ad 11679 and then Is_Constrained (Etype (Subtype_Mark (N)));
5d09245e 11680
83bb90af
TQ
11681 -- For all other names, it is sufficient to have a constrained
11682 -- Unchecked_Union nominal subtype.
11683
11684 else
11685 return Is_Unchecked_Union (Base_Type (Etype (N)))
11686 and then Is_Constrained (Etype (N));
11687 end if;
5d09245e
AC
11688 end Has_Inferable_Discriminants;
11689
70482933
RK
11690 -------------------------------
11691 -- Insert_Dereference_Action --
11692 -------------------------------
11693
11694 procedure Insert_Dereference_Action (N : Node_Id) is
8777c5a6 11695
70482933 11696 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
2e071734
AC
11697 -- Return true if type of P is derived from Checked_Pool;
11698
11699 -----------------------------
11700 -- Is_Checked_Storage_Pool --
11701 -----------------------------
70482933
RK
11702
11703 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
11704 T : Entity_Id;
761f7dcb 11705
70482933
RK
11706 begin
11707 if No (P) then
11708 return False;
11709 end if;
11710
11711 T := Etype (P);
11712 while T /= Etype (T) loop
11713 if Is_RTE (T, RE_Checked_Pool) then
11714 return True;
11715 else
11716 T := Etype (T);
11717 end if;
11718 end loop;
11719
11720 return False;
11721 end Is_Checked_Storage_Pool;
11722
b0d71355
HK
11723 -- Local variables
11724
11725 Typ : constant Entity_Id := Etype (N);
11726 Desig : constant Entity_Id := Available_View (Designated_Type (Typ));
11727 Loc : constant Source_Ptr := Sloc (N);
11728 Pool : constant Entity_Id := Associated_Storage_Pool (Typ);
11729 Pnod : constant Node_Id := Parent (N);
11730
51dcceec
AC
11731 Addr : Entity_Id;
11732 Alig : Entity_Id;
11733 Deref : Node_Id;
11734 Size : Entity_Id;
11735 Size_Bits : Node_Id;
11736 Stmt : Node_Id;
b0d71355 11737
70482933
RK
11738 -- Start of processing for Insert_Dereference_Action
11739
11740 begin
e6f69614
AC
11741 pragma Assert (Nkind (Pnod) = N_Explicit_Dereference);
11742
b0d71355
HK
11743 -- Do not re-expand a dereference which has already been processed by
11744 -- this routine.
11745
11746 if Has_Dereference_Action (Pnod) then
70482933 11747 return;
70482933 11748
b0d71355
HK
11749 -- Do not perform this type of expansion for internally-generated
11750 -- dereferences.
70482933 11751
b0d71355
HK
11752 elsif not Comes_From_Source (Original_Node (Pnod)) then
11753 return;
70482933 11754
b0d71355
HK
11755 -- A dereference action is only applicable to objects which have been
11756 -- allocated on a checked pool.
70482933 11757
b0d71355
HK
11758 elsif not Is_Checked_Storage_Pool (Pool) then
11759 return;
11760 end if;
70482933 11761
b0d71355 11762 -- Extract the address of the dereferenced object. Generate:
8777c5a6 11763
b0d71355 11764 -- Addr : System.Address := <N>'Pool_Address;
70482933 11765
b0d71355 11766 Addr := Make_Temporary (Loc, 'P');
70482933 11767
b0d71355
HK
11768 Insert_Action (N,
11769 Make_Object_Declaration (Loc,
11770 Defining_Identifier => Addr,
11771 Object_Definition =>
e4494292 11772 New_Occurrence_Of (RTE (RE_Address), Loc),
b0d71355
HK
11773 Expression =>
11774 Make_Attribute_Reference (Loc,
11775 Prefix => Duplicate_Subexpr_Move_Checks (N),
11776 Attribute_Name => Name_Pool_Address)));
11777
11778 -- Calculate the size of the dereferenced object. Generate:
8777c5a6 11779
b0d71355
HK
11780 -- Size : Storage_Count := <N>.all'Size / Storage_Unit;
11781
11782 Deref :=
11783 Make_Explicit_Dereference (Loc,
11784 Prefix => Duplicate_Subexpr_Move_Checks (N));
11785 Set_Has_Dereference_Action (Deref);
70482933 11786
51dcceec
AC
11787 Size_Bits :=
11788 Make_Attribute_Reference (Loc,
11789 Prefix => Deref,
11790 Attribute_Name => Name_Size);
11791
11792 -- Special case of an unconstrained array: need to add descriptor size
11793
11794 if Is_Array_Type (Desig)
11795 and then not Is_Constrained (First_Subtype (Desig))
11796 then
11797 Size_Bits :=
11798 Make_Op_Add (Loc,
11799 Left_Opnd =>
11800 Make_Attribute_Reference (Loc,
11801 Prefix =>
11802 New_Occurrence_Of (First_Subtype (Desig), Loc),
11803 Attribute_Name => Name_Descriptor_Size),
11804 Right_Opnd => Size_Bits);
11805 end if;
b0d71355 11806
51dcceec 11807 Size := Make_Temporary (Loc, 'S');
b0d71355
HK
11808 Insert_Action (N,
11809 Make_Object_Declaration (Loc,
11810 Defining_Identifier => Size,
11811 Object_Definition =>
e4494292 11812 New_Occurrence_Of (RTE (RE_Storage_Count), Loc),
b0d71355
HK
11813 Expression =>
11814 Make_Op_Divide (Loc,
51dcceec
AC
11815 Left_Opnd => Size_Bits,
11816 Right_Opnd => Make_Integer_Literal (Loc, System_Storage_Unit))));
70482933 11817
b0d71355
HK
11818 -- Calculate the alignment of the dereferenced object. Generate:
11819 -- Alig : constant Storage_Count := <N>.all'Alignment;
70482933 11820
b0d71355
HK
11821 Deref :=
11822 Make_Explicit_Dereference (Loc,
11823 Prefix => Duplicate_Subexpr_Move_Checks (N));
11824 Set_Has_Dereference_Action (Deref);
11825
11826 Alig := Make_Temporary (Loc, 'A');
b0d71355
HK
11827 Insert_Action (N,
11828 Make_Object_Declaration (Loc,
11829 Defining_Identifier => Alig,
11830 Object_Definition =>
e4494292 11831 New_Occurrence_Of (RTE (RE_Storage_Count), Loc),
b0d71355
HK
11832 Expression =>
11833 Make_Attribute_Reference (Loc,
11834 Prefix => Deref,
11835 Attribute_Name => Name_Alignment)));
11836
11837 -- A dereference of a controlled object requires special processing. The
11838 -- finalization machinery requests additional space from the underlying
11839 -- pool to allocate and hide two pointers. As a result, a checked pool
11840 -- may mark the wrong memory as valid. Since checked pools do not have
11841 -- knowledge of hidden pointers, we have to bring the two pointers back
11842 -- in view in order to restore the original state of the object.
11843
11844 if Needs_Finalization (Desig) then
11845
11846 -- Adjust the address and size of the dereferenced object. Generate:
11847 -- Adjust_Controlled_Dereference (Addr, Size, Alig);
11848
11849 Stmt :=
11850 Make_Procedure_Call_Statement (Loc,
11851 Name =>
e4494292 11852 New_Occurrence_Of (RTE (RE_Adjust_Controlled_Dereference), Loc),
b0d71355 11853 Parameter_Associations => New_List (
e4494292
RD
11854 New_Occurrence_Of (Addr, Loc),
11855 New_Occurrence_Of (Size, Loc),
11856 New_Occurrence_Of (Alig, Loc)));
b0d71355
HK
11857
11858 -- Class-wide types complicate things because we cannot determine
11859 -- statically whether the actual object is truly controlled. We must
11860 -- generate a runtime check to detect this property. Generate:
11861 --
11862 -- if Needs_Finalization (<N>.all'Tag) then
11863 -- <Stmt>;
11864 -- end if;
11865
11866 if Is_Class_Wide_Type (Desig) then
11867 Deref :=
11868 Make_Explicit_Dereference (Loc,
11869 Prefix => Duplicate_Subexpr_Move_Checks (N));
11870 Set_Has_Dereference_Action (Deref);
11871
11872 Stmt :=
8b1011c0 11873 Make_Implicit_If_Statement (N,
b0d71355
HK
11874 Condition =>
11875 Make_Function_Call (Loc,
11876 Name =>
e4494292 11877 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
b0d71355
HK
11878 Parameter_Associations => New_List (
11879 Make_Attribute_Reference (Loc,
11880 Prefix => Deref,
11881 Attribute_Name => Name_Tag))),
11882 Then_Statements => New_List (Stmt));
11883 end if;
11884
11885 Insert_Action (N, Stmt);
11886 end if;
11887
11888 -- Generate:
11889 -- Dereference (Pool, Addr, Size, Alig);
11890
11891 Insert_Action (N,
11892 Make_Procedure_Call_Statement (Loc,
11893 Name =>
e4494292 11894 New_Occurrence_Of
b0d71355
HK
11895 (Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
11896 Parameter_Associations => New_List (
e4494292
RD
11897 New_Occurrence_Of (Pool, Loc),
11898 New_Occurrence_Of (Addr, Loc),
11899 New_Occurrence_Of (Size, Loc),
11900 New_Occurrence_Of (Alig, Loc))));
b0d71355
HK
11901
11902 -- Mark the explicit dereference as processed to avoid potential
11903 -- infinite expansion.
11904
11905 Set_Has_Dereference_Action (Pnod);
70482933 11906
fbf5a39b
AC
11907 exception
11908 when RE_Not_Available =>
11909 return;
70482933
RK
11910 end Insert_Dereference_Action;
11911
fdfcc663
AC
11912 --------------------------------
11913 -- Integer_Promotion_Possible --
11914 --------------------------------
11915
11916 function Integer_Promotion_Possible (N : Node_Id) return Boolean is
11917 Operand : constant Node_Id := Expression (N);
11918 Operand_Type : constant Entity_Id := Etype (Operand);
11919 Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type);
11920
11921 begin
11922 pragma Assert (Nkind (N) = N_Type_Conversion);
11923
11924 return
11925
11926 -- We only do the transformation for source constructs. We assume
11927 -- that the expander knows what it is doing when it generates code.
11928
11929 Comes_From_Source (N)
11930
11931 -- If the operand type is Short_Integer or Short_Short_Integer,
11932 -- then we will promote to Integer, which is available on all
11933 -- targets, and is sufficient to ensure no intermediate overflow.
11934 -- Furthermore it is likely to be as efficient or more efficient
11935 -- than using the smaller type for the computation so we do this
11936 -- unconditionally.
11937
11938 and then
11939 (Root_Operand_Type = Base_Type (Standard_Short_Integer)
761f7dcb 11940 or else
fdfcc663
AC
11941 Root_Operand_Type = Base_Type (Standard_Short_Short_Integer))
11942
11943 -- Test for interesting operation, which includes addition,
5f3f175d
AC
11944 -- division, exponentiation, multiplication, subtraction, absolute
11945 -- value and unary negation. Unary "+" is omitted since it is a
11946 -- no-op and thus can't overflow.
fdfcc663 11947
5f3f175d
AC
11948 and then Nkind_In (Operand, N_Op_Abs,
11949 N_Op_Add,
fdfcc663
AC
11950 N_Op_Divide,
11951 N_Op_Expon,
11952 N_Op_Minus,
11953 N_Op_Multiply,
11954 N_Op_Subtract);
11955 end Integer_Promotion_Possible;
11956
70482933
RK
11957 ------------------------------
11958 -- Make_Array_Comparison_Op --
11959 ------------------------------
11960
11961 -- This is a hand-coded expansion of the following generic function:
11962
11963 -- generic
11964 -- type elem is (<>);
11965 -- type index is (<>);
11966 -- type a is array (index range <>) of elem;
20b5d666 11967
70482933
RK
11968 -- function Gnnn (X : a; Y: a) return boolean is
11969 -- J : index := Y'first;
20b5d666 11970
70482933
RK
11971 -- begin
11972 -- if X'length = 0 then
11973 -- return false;
20b5d666 11974
70482933
RK
11975 -- elsif Y'length = 0 then
11976 -- return true;
20b5d666 11977
70482933
RK
11978 -- else
11979 -- for I in X'range loop
11980 -- if X (I) = Y (J) then
11981 -- if J = Y'last then
11982 -- exit;
11983 -- else
11984 -- J := index'succ (J);
11985 -- end if;
20b5d666 11986
70482933
RK
11987 -- else
11988 -- return X (I) > Y (J);
11989 -- end if;
11990 -- end loop;
20b5d666 11991
70482933
RK
11992 -- return X'length > Y'length;
11993 -- end if;
11994 -- end Gnnn;
11995
11996 -- Note that since we are essentially doing this expansion by hand, we
11997 -- do not need to generate an actual or formal generic part, just the
11998 -- instantiated function itself.
11999
bb012790
AC
12000 -- Perhaps we could have the actual generic available in the run-time,
12001 -- obtained by rtsfind, and actually expand a real instantiation ???
12002
70482933 12003 function Make_Array_Comparison_Op
2e071734
AC
12004 (Typ : Entity_Id;
12005 Nod : Node_Id) return Node_Id
70482933
RK
12006 is
12007 Loc : constant Source_Ptr := Sloc (Nod);
12008
12009 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
12010 Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
12011 I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
12012 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
12013
12014 Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
12015
12016 Loop_Statement : Node_Id;
12017 Loop_Body : Node_Id;
12018 If_Stat : Node_Id;
12019 Inner_If : Node_Id;
12020 Final_Expr : Node_Id;
12021 Func_Body : Node_Id;
12022 Func_Name : Entity_Id;
12023 Formals : List_Id;
12024 Length1 : Node_Id;
12025 Length2 : Node_Id;
12026
12027 begin
12028 -- if J = Y'last then
12029 -- exit;
12030 -- else
12031 -- J := index'succ (J);
12032 -- end if;
12033
12034 Inner_If :=
12035 Make_Implicit_If_Statement (Nod,
12036 Condition =>
12037 Make_Op_Eq (Loc,
e4494292 12038 Left_Opnd => New_Occurrence_Of (J, Loc),
70482933
RK
12039 Right_Opnd =>
12040 Make_Attribute_Reference (Loc,
e4494292 12041 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
12042 Attribute_Name => Name_Last)),
12043
12044 Then_Statements => New_List (
12045 Make_Exit_Statement (Loc)),
12046
12047 Else_Statements =>
12048 New_List (
12049 Make_Assignment_Statement (Loc,
e4494292 12050 Name => New_Occurrence_Of (J, Loc),
70482933
RK
12051 Expression =>
12052 Make_Attribute_Reference (Loc,
e4494292 12053 Prefix => New_Occurrence_Of (Index, Loc),
70482933 12054 Attribute_Name => Name_Succ,
e4494292 12055 Expressions => New_List (New_Occurrence_Of (J, Loc))))));
70482933
RK
12056
12057 -- if X (I) = Y (J) then
12058 -- if ... end if;
12059 -- else
12060 -- return X (I) > Y (J);
12061 -- end if;
12062
12063 Loop_Body :=
12064 Make_Implicit_If_Statement (Nod,
12065 Condition =>
12066 Make_Op_Eq (Loc,
12067 Left_Opnd =>
12068 Make_Indexed_Component (Loc,
e4494292
RD
12069 Prefix => New_Occurrence_Of (X, Loc),
12070 Expressions => New_List (New_Occurrence_Of (I, Loc))),
70482933
RK
12071
12072 Right_Opnd =>
12073 Make_Indexed_Component (Loc,
e4494292
RD
12074 Prefix => New_Occurrence_Of (Y, Loc),
12075 Expressions => New_List (New_Occurrence_Of (J, Loc)))),
70482933
RK
12076
12077 Then_Statements => New_List (Inner_If),
12078
12079 Else_Statements => New_List (
d766cee3 12080 Make_Simple_Return_Statement (Loc,
70482933
RK
12081 Expression =>
12082 Make_Op_Gt (Loc,
12083 Left_Opnd =>
12084 Make_Indexed_Component (Loc,
e4494292
RD
12085 Prefix => New_Occurrence_Of (X, Loc),
12086 Expressions => New_List (New_Occurrence_Of (I, Loc))),
70482933
RK
12087
12088 Right_Opnd =>
12089 Make_Indexed_Component (Loc,
e4494292 12090 Prefix => New_Occurrence_Of (Y, Loc),
70482933 12091 Expressions => New_List (
e4494292 12092 New_Occurrence_Of (J, Loc)))))));
70482933
RK
12093
12094 -- for I in X'range loop
12095 -- if ... end if;
12096 -- end loop;
12097
12098 Loop_Statement :=
12099 Make_Implicit_Loop_Statement (Nod,
12100 Identifier => Empty,
12101
12102 Iteration_Scheme =>
12103 Make_Iteration_Scheme (Loc,
12104 Loop_Parameter_Specification =>
12105 Make_Loop_Parameter_Specification (Loc,
12106 Defining_Identifier => I,
12107 Discrete_Subtype_Definition =>
12108 Make_Attribute_Reference (Loc,
e4494292 12109 Prefix => New_Occurrence_Of (X, Loc),
70482933
RK
12110 Attribute_Name => Name_Range))),
12111
12112 Statements => New_List (Loop_Body));
12113
12114 -- if X'length = 0 then
12115 -- return false;
12116 -- elsif Y'length = 0 then
12117 -- return true;
12118 -- else
12119 -- for ... loop ... end loop;
12120 -- return X'length > Y'length;
12121 -- end if;
12122
12123 Length1 :=
12124 Make_Attribute_Reference (Loc,
e4494292 12125 Prefix => New_Occurrence_Of (X, Loc),
70482933
RK
12126 Attribute_Name => Name_Length);
12127
12128 Length2 :=
12129 Make_Attribute_Reference (Loc,
e4494292 12130 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
12131 Attribute_Name => Name_Length);
12132
12133 Final_Expr :=
12134 Make_Op_Gt (Loc,
12135 Left_Opnd => Length1,
12136 Right_Opnd => Length2);
12137
12138 If_Stat :=
12139 Make_Implicit_If_Statement (Nod,
12140 Condition =>
12141 Make_Op_Eq (Loc,
12142 Left_Opnd =>
12143 Make_Attribute_Reference (Loc,
e4494292 12144 Prefix => New_Occurrence_Of (X, Loc),
70482933
RK
12145 Attribute_Name => Name_Length),
12146 Right_Opnd =>
12147 Make_Integer_Literal (Loc, 0)),
12148
12149 Then_Statements =>
12150 New_List (
d766cee3 12151 Make_Simple_Return_Statement (Loc,
e4494292 12152 Expression => New_Occurrence_Of (Standard_False, Loc))),
70482933
RK
12153
12154 Elsif_Parts => New_List (
12155 Make_Elsif_Part (Loc,
12156 Condition =>
12157 Make_Op_Eq (Loc,
12158 Left_Opnd =>
12159 Make_Attribute_Reference (Loc,
e4494292 12160 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
12161 Attribute_Name => Name_Length),
12162 Right_Opnd =>
12163 Make_Integer_Literal (Loc, 0)),
12164
12165 Then_Statements =>
12166 New_List (
d766cee3 12167 Make_Simple_Return_Statement (Loc,
e4494292 12168 Expression => New_Occurrence_Of (Standard_True, Loc))))),
70482933
RK
12169
12170 Else_Statements => New_List (
12171 Loop_Statement,
d766cee3 12172 Make_Simple_Return_Statement (Loc,
70482933
RK
12173 Expression => Final_Expr)));
12174
12175 -- (X : a; Y: a)
12176
12177 Formals := New_List (
12178 Make_Parameter_Specification (Loc,
12179 Defining_Identifier => X,
e4494292 12180 Parameter_Type => New_Occurrence_Of (Typ, Loc)),
70482933
RK
12181
12182 Make_Parameter_Specification (Loc,
12183 Defining_Identifier => Y,
e4494292 12184 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
70482933
RK
12185
12186 -- function Gnnn (...) return boolean is
12187 -- J : index := Y'first;
12188 -- begin
12189 -- if ... end if;
12190 -- end Gnnn;
12191
191fcb3a 12192 Func_Name := Make_Temporary (Loc, 'G');
70482933
RK
12193
12194 Func_Body :=
12195 Make_Subprogram_Body (Loc,
12196 Specification =>
12197 Make_Function_Specification (Loc,
12198 Defining_Unit_Name => Func_Name,
12199 Parameter_Specifications => Formals,
e4494292 12200 Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),
70482933
RK
12201
12202 Declarations => New_List (
12203 Make_Object_Declaration (Loc,
12204 Defining_Identifier => J,
e4494292 12205 Object_Definition => New_Occurrence_Of (Index, Loc),
70482933
RK
12206 Expression =>
12207 Make_Attribute_Reference (Loc,
e4494292 12208 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
12209 Attribute_Name => Name_First))),
12210
12211 Handled_Statement_Sequence =>
12212 Make_Handled_Sequence_Of_Statements (Loc,
12213 Statements => New_List (If_Stat)));
12214
12215 return Func_Body;
70482933
RK
12216 end Make_Array_Comparison_Op;
12217
12218 ---------------------------
12219 -- Make_Boolean_Array_Op --
12220 ---------------------------
12221
685094bf
RD
12222 -- For logical operations on boolean arrays, expand in line the following,
12223 -- replacing 'and' with 'or' or 'xor' where needed:
70482933
RK
12224
12225 -- function Annn (A : typ; B: typ) return typ is
12226 -- C : typ;
12227 -- begin
12228 -- for J in A'range loop
12229 -- C (J) := A (J) op B (J);
12230 -- end loop;
12231 -- return C;
12232 -- end Annn;
12233
12234 -- Here typ is the boolean array type
12235
12236 function Make_Boolean_Array_Op
2e071734
AC
12237 (Typ : Entity_Id;
12238 N : Node_Id) return Node_Id
70482933
RK
12239 is
12240 Loc : constant Source_Ptr := Sloc (N);
12241
12242 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
12243 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
12244 C : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uC);
12245 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
12246
12247 A_J : Node_Id;
12248 B_J : Node_Id;
12249 C_J : Node_Id;
12250 Op : Node_Id;
12251
12252 Formals : List_Id;
12253 Func_Name : Entity_Id;
12254 Func_Body : Node_Id;
12255 Loop_Statement : Node_Id;
12256
12257 begin
12258 A_J :=
12259 Make_Indexed_Component (Loc,
e4494292
RD
12260 Prefix => New_Occurrence_Of (A, Loc),
12261 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
12262
12263 B_J :=
12264 Make_Indexed_Component (Loc,
e4494292
RD
12265 Prefix => New_Occurrence_Of (B, Loc),
12266 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
12267
12268 C_J :=
12269 Make_Indexed_Component (Loc,
e4494292
RD
12270 Prefix => New_Occurrence_Of (C, Loc),
12271 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
12272
12273 if Nkind (N) = N_Op_And then
12274 Op :=
12275 Make_Op_And (Loc,
12276 Left_Opnd => A_J,
12277 Right_Opnd => B_J);
12278
12279 elsif Nkind (N) = N_Op_Or then
12280 Op :=
12281 Make_Op_Or (Loc,
12282 Left_Opnd => A_J,
12283 Right_Opnd => B_J);
12284
12285 else
12286 Op :=
12287 Make_Op_Xor (Loc,
12288 Left_Opnd => A_J,
12289 Right_Opnd => B_J);
12290 end if;
12291
12292 Loop_Statement :=
12293 Make_Implicit_Loop_Statement (N,
12294 Identifier => Empty,
12295
12296 Iteration_Scheme =>
12297 Make_Iteration_Scheme (Loc,
12298 Loop_Parameter_Specification =>
12299 Make_Loop_Parameter_Specification (Loc,
12300 Defining_Identifier => J,
12301 Discrete_Subtype_Definition =>
12302 Make_Attribute_Reference (Loc,
e4494292 12303 Prefix => New_Occurrence_Of (A, Loc),
70482933
RK
12304 Attribute_Name => Name_Range))),
12305
12306 Statements => New_List (
12307 Make_Assignment_Statement (Loc,
12308 Name => C_J,
12309 Expression => Op)));
12310
12311 Formals := New_List (
12312 Make_Parameter_Specification (Loc,
12313 Defining_Identifier => A,
e4494292 12314 Parameter_Type => New_Occurrence_Of (Typ, Loc)),
70482933
RK
12315
12316 Make_Parameter_Specification (Loc,
12317 Defining_Identifier => B,
e4494292 12318 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
70482933 12319
191fcb3a 12320 Func_Name := Make_Temporary (Loc, 'A');
70482933
RK
12321 Set_Is_Inlined (Func_Name);
12322
12323 Func_Body :=
12324 Make_Subprogram_Body (Loc,
12325 Specification =>
12326 Make_Function_Specification (Loc,
12327 Defining_Unit_Name => Func_Name,
12328 Parameter_Specifications => Formals,
e4494292 12329 Result_Definition => New_Occurrence_Of (Typ, Loc)),
70482933
RK
12330
12331 Declarations => New_List (
12332 Make_Object_Declaration (Loc,
12333 Defining_Identifier => C,
e4494292 12334 Object_Definition => New_Occurrence_Of (Typ, Loc))),
70482933
RK
12335
12336 Handled_Statement_Sequence =>
12337 Make_Handled_Sequence_Of_Statements (Loc,
12338 Statements => New_List (
12339 Loop_Statement,
d766cee3 12340 Make_Simple_Return_Statement (Loc,
e4494292 12341 Expression => New_Occurrence_Of (C, Loc)))));
70482933
RK
12342
12343 return Func_Body;
12344 end Make_Boolean_Array_Op;
12345
b6b5cca8
AC
12346 -----------------------------------------
12347 -- Minimized_Eliminated_Overflow_Check --
12348 -----------------------------------------
12349
12350 function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean is
12351 begin
12352 return
12353 Is_Signed_Integer_Type (Etype (N))
a7f1b24f 12354 and then Overflow_Check_Mode in Minimized_Or_Eliminated;
b6b5cca8
AC
12355 end Minimized_Eliminated_Overflow_Check;
12356
0580d807
AC
12357 --------------------------------
12358 -- Optimize_Length_Comparison --
12359 --------------------------------
12360
12361 procedure Optimize_Length_Comparison (N : Node_Id) is
12362 Loc : constant Source_Ptr := Sloc (N);
12363 Typ : constant Entity_Id := Etype (N);
12364 Result : Node_Id;
12365
12366 Left : Node_Id;
12367 Right : Node_Id;
12368 -- First and Last attribute reference nodes, which end up as left and
12369 -- right operands of the optimized result.
12370
12371 Is_Zero : Boolean;
12372 -- True for comparison operand of zero
12373
12374 Comp : Node_Id;
12375 -- Comparison operand, set only if Is_Zero is false
12376
12377 Ent : Entity_Id;
12378 -- Entity whose length is being compared
12379
12380 Index : Node_Id;
12381 -- Integer_Literal node for length attribute expression, or Empty
12382 -- if there is no such expression present.
12383
12384 Ityp : Entity_Id;
12385 -- Type of array index to which 'Length is applied
12386
12387 Op : Node_Kind := Nkind (N);
12388 -- Kind of comparison operator, gets flipped if operands backwards
12389
12390 function Is_Optimizable (N : Node_Id) return Boolean;
abcd9db2
AC
12391 -- Tests N to see if it is an optimizable comparison value (defined as
12392 -- constant zero or one, or something else where the value is known to
12393 -- be positive and in the range of 32-bits, and where the corresponding
12394 -- Length value is also known to be 32-bits. If result is true, sets
12395 -- Is_Zero, Ityp, and Comp accordingly.
0580d807
AC
12396
12397 function Is_Entity_Length (N : Node_Id) return Boolean;
12398 -- Tests if N is a length attribute applied to a simple entity. If so,
12399 -- returns True, and sets Ent to the entity, and Index to the integer
12400 -- literal provided as an attribute expression, or to Empty if none.
12401 -- Also returns True if the expression is a generated type conversion
12402 -- whose expression is of the desired form. This latter case arises
12403 -- when Apply_Universal_Integer_Attribute_Check installs a conversion
12404 -- to check for being in range, which is not needed in this context.
12405 -- Returns False if neither condition holds.
12406
12407 function Prepare_64 (N : Node_Id) return Node_Id;
12408 -- Given a discrete expression, returns a Long_Long_Integer typed
12409 -- expression representing the underlying value of the expression.
12410 -- This is done with an unchecked conversion to the result type. We
12411 -- use unchecked conversion to handle the enumeration type case.
12412
12413 ----------------------
12414 -- Is_Entity_Length --
12415 ----------------------
12416
12417 function Is_Entity_Length (N : Node_Id) return Boolean is
12418 begin
12419 if Nkind (N) = N_Attribute_Reference
12420 and then Attribute_Name (N) = Name_Length
12421 and then Is_Entity_Name (Prefix (N))
12422 then
12423 Ent := Entity (Prefix (N));
12424
12425 if Present (Expressions (N)) then
12426 Index := First (Expressions (N));
12427 else
12428 Index := Empty;
12429 end if;
12430
12431 return True;
12432
12433 elsif Nkind (N) = N_Type_Conversion
12434 and then not Comes_From_Source (N)
12435 then
12436 return Is_Entity_Length (Expression (N));
12437
12438 else
12439 return False;
12440 end if;
12441 end Is_Entity_Length;
12442
12443 --------------------
12444 -- Is_Optimizable --
12445 --------------------
12446
12447 function Is_Optimizable (N : Node_Id) return Boolean is
12448 Val : Uint;
12449 OK : Boolean;
12450 Lo : Uint;
12451 Hi : Uint;
12452 Indx : Node_Id;
12453
12454 begin
12455 if Compile_Time_Known_Value (N) then
12456 Val := Expr_Value (N);
12457
12458 if Val = Uint_0 then
12459 Is_Zero := True;
12460 Comp := Empty;
12461 return True;
12462
12463 elsif Val = Uint_1 then
12464 Is_Zero := False;
12465 Comp := Empty;
12466 return True;
12467 end if;
12468 end if;
12469
12470 -- Here we have to make sure of being within 32-bits
12471
12472 Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
12473
12474 if not OK
abcd9db2 12475 or else Lo < Uint_1
0580d807
AC
12476 or else Hi > UI_From_Int (Int'Last)
12477 then
12478 return False;
12479 end if;
12480
abcd9db2
AC
12481 -- Comparison value was within range, so now we must check the index
12482 -- value to make sure it is also within 32-bits.
0580d807
AC
12483
12484 Indx := First_Index (Etype (Ent));
12485
12486 if Present (Index) then
12487 for J in 2 .. UI_To_Int (Intval (Index)) loop
12488 Next_Index (Indx);
12489 end loop;
12490 end if;
12491
12492 Ityp := Etype (Indx);
12493
12494 if Esize (Ityp) > 32 then
12495 return False;
12496 end if;
12497
12498 Is_Zero := False;
12499 Comp := N;
12500 return True;
12501 end Is_Optimizable;
12502
12503 ----------------
12504 -- Prepare_64 --
12505 ----------------
12506
12507 function Prepare_64 (N : Node_Id) return Node_Id is
12508 begin
12509 return Unchecked_Convert_To (Standard_Long_Long_Integer, N);
12510 end Prepare_64;
12511
12512 -- Start of processing for Optimize_Length_Comparison
12513
12514 begin
12515 -- Nothing to do if not a comparison
12516
12517 if Op not in N_Op_Compare then
12518 return;
12519 end if;
12520
12521 -- Nothing to do if special -gnatd.P debug flag set
12522
12523 if Debug_Flag_Dot_PP then
12524 return;
12525 end if;
12526
12527 -- Ent'Length op 0/1
12528
12529 if Is_Entity_Length (Left_Opnd (N))
12530 and then Is_Optimizable (Right_Opnd (N))
12531 then
12532 null;
12533
12534 -- 0/1 op Ent'Length
12535
12536 elsif Is_Entity_Length (Right_Opnd (N))
12537 and then Is_Optimizable (Left_Opnd (N))
12538 then
12539 -- Flip comparison to opposite sense
12540
12541 case Op is
12542 when N_Op_Lt => Op := N_Op_Gt;
12543 when N_Op_Le => Op := N_Op_Ge;
12544 when N_Op_Gt => Op := N_Op_Lt;
12545 when N_Op_Ge => Op := N_Op_Le;
12546 when others => null;
12547 end case;
12548
12549 -- Else optimization not possible
12550
12551 else
12552 return;
12553 end if;
12554
12555 -- Fall through if we will do the optimization
12556
12557 -- Cases to handle:
12558
12559 -- X'Length = 0 => X'First > X'Last
12560 -- X'Length = 1 => X'First = X'Last
12561 -- X'Length = n => X'First + (n - 1) = X'Last
12562
12563 -- X'Length /= 0 => X'First <= X'Last
12564 -- X'Length /= 1 => X'First /= X'Last
12565 -- X'Length /= n => X'First + (n - 1) /= X'Last
12566
12567 -- X'Length >= 0 => always true, warn
12568 -- X'Length >= 1 => X'First <= X'Last
12569 -- X'Length >= n => X'First + (n - 1) <= X'Last
12570
12571 -- X'Length > 0 => X'First <= X'Last
12572 -- X'Length > 1 => X'First < X'Last
12573 -- X'Length > n => X'First + (n - 1) < X'Last
12574
12575 -- X'Length <= 0 => X'First > X'Last (warn, could be =)
12576 -- X'Length <= 1 => X'First >= X'Last
12577 -- X'Length <= n => X'First + (n - 1) >= X'Last
12578
12579 -- X'Length < 0 => always false (warn)
12580 -- X'Length < 1 => X'First > X'Last
12581 -- X'Length < n => X'First + (n - 1) > X'Last
12582
12583 -- Note: for the cases of n (not constant 0,1), we require that the
12584 -- corresponding index type be integer or shorter (i.e. not 64-bit),
12585 -- and the same for the comparison value. Then we do the comparison
12586 -- using 64-bit arithmetic (actually long long integer), so that we
12587 -- cannot have overflow intefering with the result.
12588
12589 -- First deal with warning cases
12590
12591 if Is_Zero then
12592 case Op is
12593
12594 -- X'Length >= 0
12595
12596 when N_Op_Ge =>
12597 Rewrite (N,
12598 Convert_To (Typ, New_Occurrence_Of (Standard_True, Loc)));
12599 Analyze_And_Resolve (N, Typ);
12600 Warn_On_Known_Condition (N);
12601 return;
12602
12603 -- X'Length < 0
12604
12605 when N_Op_Lt =>
12606 Rewrite (N,
12607 Convert_To (Typ, New_Occurrence_Of (Standard_False, Loc)));
12608 Analyze_And_Resolve (N, Typ);
12609 Warn_On_Known_Condition (N);
12610 return;
12611
12612 when N_Op_Le =>
12613 if Constant_Condition_Warnings
12614 and then Comes_From_Source (Original_Node (N))
12615 then
324ac540 12616 Error_Msg_N ("could replace by ""'=""?c?", N);
0580d807
AC
12617 end if;
12618
12619 Op := N_Op_Eq;
12620
12621 when others =>
12622 null;
12623 end case;
12624 end if;
12625
12626 -- Build the First reference we will use
12627
12628 Left :=
12629 Make_Attribute_Reference (Loc,
12630 Prefix => New_Occurrence_Of (Ent, Loc),
12631 Attribute_Name => Name_First);
12632
12633 if Present (Index) then
12634 Set_Expressions (Left, New_List (New_Copy (Index)));
12635 end if;
12636
12637 -- If general value case, then do the addition of (n - 1), and
12638 -- also add the needed conversions to type Long_Long_Integer.
12639
12640 if Present (Comp) then
12641 Left :=
12642 Make_Op_Add (Loc,
12643 Left_Opnd => Prepare_64 (Left),
12644 Right_Opnd =>
12645 Make_Op_Subtract (Loc,
12646 Left_Opnd => Prepare_64 (Comp),
12647 Right_Opnd => Make_Integer_Literal (Loc, 1)));
12648 end if;
12649
12650 -- Build the Last reference we will use
12651
12652 Right :=
12653 Make_Attribute_Reference (Loc,
12654 Prefix => New_Occurrence_Of (Ent, Loc),
12655 Attribute_Name => Name_Last);
12656
12657 if Present (Index) then
12658 Set_Expressions (Right, New_List (New_Copy (Index)));
12659 end if;
12660
12661 -- If general operand, convert Last reference to Long_Long_Integer
12662
12663 if Present (Comp) then
12664 Right := Prepare_64 (Right);
12665 end if;
12666
12667 -- Check for cases to optimize
12668
12669 -- X'Length = 0 => X'First > X'Last
12670 -- X'Length < 1 => X'First > X'Last
12671 -- X'Length < n => X'First + (n - 1) > X'Last
12672
12673 if (Is_Zero and then Op = N_Op_Eq)
12674 or else (not Is_Zero and then Op = N_Op_Lt)
12675 then
12676 Result :=
12677 Make_Op_Gt (Loc,
12678 Left_Opnd => Left,
12679 Right_Opnd => Right);
12680
12681 -- X'Length = 1 => X'First = X'Last
12682 -- X'Length = n => X'First + (n - 1) = X'Last
12683
12684 elsif not Is_Zero and then Op = N_Op_Eq then
12685 Result :=
12686 Make_Op_Eq (Loc,
12687 Left_Opnd => Left,
12688 Right_Opnd => Right);
12689
12690 -- X'Length /= 0 => X'First <= X'Last
12691 -- X'Length > 0 => X'First <= X'Last
12692
12693 elsif Is_Zero and (Op = N_Op_Ne or else Op = N_Op_Gt) then
12694 Result :=
12695 Make_Op_Le (Loc,
12696 Left_Opnd => Left,
12697 Right_Opnd => Right);
12698
12699 -- X'Length /= 1 => X'First /= X'Last
12700 -- X'Length /= n => X'First + (n - 1) /= X'Last
12701
12702 elsif not Is_Zero and then Op = N_Op_Ne then
12703 Result :=
12704 Make_Op_Ne (Loc,
12705 Left_Opnd => Left,
12706 Right_Opnd => Right);
12707
12708 -- X'Length >= 1 => X'First <= X'Last
12709 -- X'Length >= n => X'First + (n - 1) <= X'Last
12710
12711 elsif not Is_Zero and then Op = N_Op_Ge then
12712 Result :=
12713 Make_Op_Le (Loc,
12714 Left_Opnd => Left,
12715 Right_Opnd => Right);
12716
12717 -- X'Length > 1 => X'First < X'Last
12718 -- X'Length > n => X'First + (n = 1) < X'Last
12719
12720 elsif not Is_Zero and then Op = N_Op_Gt then
12721 Result :=
12722 Make_Op_Lt (Loc,
12723 Left_Opnd => Left,
12724 Right_Opnd => Right);
12725
12726 -- X'Length <= 1 => X'First >= X'Last
12727 -- X'Length <= n => X'First + (n - 1) >= X'Last
12728
12729 elsif not Is_Zero and then Op = N_Op_Le then
12730 Result :=
12731 Make_Op_Ge (Loc,
12732 Left_Opnd => Left,
12733 Right_Opnd => Right);
12734
12735 -- Should not happen at this stage
12736
12737 else
12738 raise Program_Error;
12739 end if;
12740
12741 -- Rewrite and finish up
12742
12743 Rewrite (N, Result);
12744 Analyze_And_Resolve (N, Typ);
12745 return;
12746 end Optimize_Length_Comparison;
12747
b2c28399
AC
12748 ------------------------------
12749 -- Process_Transient_Object --
12750 ------------------------------
12751
12752 procedure Process_Transient_Object
12753 (Decl : Node_Id;
12754 Rel_Node : Node_Id)
12755 is
4b17187f
AC
12756 Loc : constant Source_Ptr := Sloc (Decl);
12757 Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
12758 Obj_Typ : constant Node_Id := Etype (Obj_Id);
12759 Desig_Typ : Entity_Id;
12760 Expr : Node_Id;
12761 Hook_Id : Entity_Id;
12762 Hook_Insert : Node_Id;
12763 Ptr_Id : Entity_Id;
8942b30c 12764
9ab5d86b 12765 Hook_Context : constant Node_Id := Find_Hook_Context (Rel_Node);
4b17187f
AC
12766 -- The node on which to insert the hook as an action. This is usually
12767 -- the innermost enclosing non-transient construct.
064f4527 12768
4b17187f
AC
12769 Fin_Context : Node_Id;
12770 -- The node after which to insert the finalization actions of the
12771 -- transient controlled object.
b2c28399 12772
8942b30c 12773 begin
8942b30c 12774 if Is_Boolean_Type (Etype (Rel_Node)) then
4b17187f 12775 Fin_Context := Last (Actions (Rel_Node));
8942b30c 12776 else
4b17187f 12777 Fin_Context := Hook_Context;
8942b30c 12778 end if;
064f4527 12779
b2c28399
AC
12780 -- Step 1: Create the access type which provides a reference to the
12781 -- transient controlled object.
12782
12783 if Is_Access_Type (Obj_Typ) then
12784 Desig_Typ := Directly_Designated_Type (Obj_Typ);
12785 else
12786 Desig_Typ := Obj_Typ;
12787 end if;
12788
12789 Desig_Typ := Base_Type (Desig_Typ);
12790
12791 -- Generate:
12792 -- Ann : access [all] <Desig_Typ>;
12793
12794 Ptr_Id := Make_Temporary (Loc, 'A');
12795
064f4527 12796 Insert_Action (Hook_Context,
b2c28399
AC
12797 Make_Full_Type_Declaration (Loc,
12798 Defining_Identifier => Ptr_Id,
12799 Type_Definition =>
12800 Make_Access_To_Object_Definition (Loc,
12801 All_Present => Ekind (Obj_Typ) = E_General_Access_Type,
e4494292 12802 Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc))));
b2c28399
AC
12803
12804 -- Step 2: Create a temporary which acts as a hook to the transient
12805 -- controlled object. Generate:
12806
4b17187f 12807 -- Hook : Ptr_Id := null;
b2c28399 12808
4b17187f 12809 Hook_Id := Make_Temporary (Loc, 'T');
b2c28399 12810
064f4527 12811 Insert_Action (Hook_Context,
b2c28399 12812 Make_Object_Declaration (Loc,
4b17187f 12813 Defining_Identifier => Hook_Id,
e4494292 12814 Object_Definition => New_Occurrence_Of (Ptr_Id, Loc)));
b2c28399 12815
4b17187f
AC
12816 -- Mark the hook as created for the purposes of exporting the transient
12817 -- controlled object out of the expression_with_action or if expression.
12818 -- This signals the machinery in Build_Finalizer to treat this case in
12819 -- a special manner.
b2c28399 12820
4b17187f 12821 Set_Status_Flag_Or_Transient_Decl (Hook_Id, Decl);
b2c28399 12822
4b17187f 12823 -- Step 3: Associate the transient object to the hook
b2c28399 12824
a7d08a38
AC
12825 -- This must be inserted right after the object declaration, so that
12826 -- the assignment is executed if, and only if, the object is actually
12827 -- created (whereas the declaration of the hook pointer, and the
12828 -- finalization call, may be inserted at an outer level, and may
12829 -- remain unused for some executions, if the actual creation of
12830 -- the object is conditional).
12831
b2c28399
AC
12832 -- The use of unchecked conversion / unrestricted access is needed to
12833 -- avoid an accessibility violation. Note that the finalization code is
12834 -- structured in such a way that the "hook" is processed only when it
12835 -- points to an existing object.
12836
12837 if Is_Access_Type (Obj_Typ) then
e4494292 12838 Expr :=
4b17187f
AC
12839 Unchecked_Convert_To
12840 (Typ => Ptr_Id,
12841 Expr => New_Occurrence_Of (Obj_Id, Loc));
b2c28399
AC
12842 else
12843 Expr :=
12844 Make_Attribute_Reference (Loc,
e4494292 12845 Prefix => New_Occurrence_Of (Obj_Id, Loc),
b2c28399
AC
12846 Attribute_Name => Name_Unrestricted_Access);
12847 end if;
12848
12849 -- Generate:
4b17187f 12850 -- Hook := Ptr_Id (Obj_Id);
b2c28399 12851 -- <or>
4b17187f 12852 -- Hook := Obj_Id'Unrestricted_Access;
b2c28399 12853
97779c34
AC
12854 -- When the transient object is initialized by an aggregate, the hook
12855 -- must capture the object after the last component assignment takes
12856 -- place. Only then is the object fully initialized.
12857
12858 if Ekind (Obj_Id) = E_Variable
12859 and then Present (Last_Aggregate_Assignment (Obj_Id))
12860 then
4b17187f 12861 Hook_Insert := Last_Aggregate_Assignment (Obj_Id);
97779c34
AC
12862
12863 -- Otherwise the hook seizes the related object immediately
12864
12865 else
4b17187f 12866 Hook_Insert := Decl;
97779c34
AC
12867 end if;
12868
4b17187f 12869 Insert_After_And_Analyze (Hook_Insert,
a7d08a38 12870 Make_Assignment_Statement (Loc,
4b17187f 12871 Name => New_Occurrence_Of (Hook_Id, Loc),
a7d08a38 12872 Expression => Expr));
b2c28399 12873
4b17187f
AC
12874 -- Step 4: Finalize the hook after the context has been evaluated or
12875 -- elaborated. Generate:
b2c28399 12876
4b17187f
AC
12877 -- if Hook /= null then
12878 -- [Deep_]Finalize (Hook.all);
12879 -- Hook := null;
b2c28399
AC
12880 -- end if;
12881
12882 -- When the node is part of a return statement, there is no need to
12883 -- insert a finalization call, as the general finalization mechanism
12884 -- (see Build_Finalizer) would take care of the transient controlled
12885 -- object on subprogram exit. Note that it would also be impossible to
12886 -- insert the finalization code after the return statement as this will
12887 -- render it unreachable.
12888
4b17187f
AC
12889 if Nkind (Fin_Context) = N_Simple_Return_Statement then
12890 null;
b2c28399 12891
4b17187f 12892 -- Otherwise finalize the hook
b2c28399 12893
4b17187f
AC
12894 else
12895 Insert_Action_After (Fin_Context,
12896 Make_Implicit_If_Statement (Decl,
12897 Condition =>
12898 Make_Op_Ne (Loc,
12899 Left_Opnd => New_Occurrence_Of (Hook_Id, Loc),
12900 Right_Opnd => Make_Null (Loc)),
12901
12902 Then_Statements => New_List (
12903 Make_Final_Call
12904 (Obj_Ref =>
12905 Make_Explicit_Dereference (Loc,
12906 Prefix => New_Occurrence_Of (Hook_Id, Loc)),
12907 Typ => Desig_Typ),
b2c28399 12908
4b17187f
AC
12909 Make_Assignment_Statement (Loc,
12910 Name => New_Occurrence_Of (Hook_Id, Loc),
12911 Expression => Make_Null (Loc)))));
b2c28399
AC
12912 end if;
12913 end Process_Transient_Object;
12914
70482933
RK
12915 ------------------------
12916 -- Rewrite_Comparison --
12917 ------------------------
12918
12919 procedure Rewrite_Comparison (N : Node_Id) is
c800f862
RD
12920 Warning_Generated : Boolean := False;
12921 -- Set to True if first pass with Assume_Valid generates a warning in
12922 -- which case we skip the second pass to avoid warning overloaded.
12923
12924 Result : Node_Id;
12925 -- Set to Standard_True or Standard_False
12926
d26dc4b5
AC
12927 begin
12928 if Nkind (N) = N_Type_Conversion then
12929 Rewrite_Comparison (Expression (N));
20b5d666 12930 return;
70482933 12931
d26dc4b5 12932 elsif Nkind (N) not in N_Op_Compare then
20b5d666
JM
12933 return;
12934 end if;
70482933 12935
c800f862
RD
12936 -- Now start looking at the comparison in detail. We potentially go
12937 -- through this loop twice. The first time, Assume_Valid is set False
12938 -- in the call to Compile_Time_Compare. If this call results in a
12939 -- clear result of always True or Always False, that's decisive and
12940 -- we are done. Otherwise we repeat the processing with Assume_Valid
e7e4d230 12941 -- set to True to generate additional warnings. We can skip that step
c800f862
RD
12942 -- if Constant_Condition_Warnings is False.
12943
12944 for AV in False .. True loop
12945 declare
12946 Typ : constant Entity_Id := Etype (N);
12947 Op1 : constant Node_Id := Left_Opnd (N);
12948 Op2 : constant Node_Id := Right_Opnd (N);
70482933 12949
c800f862
RD
12950 Res : constant Compare_Result :=
12951 Compile_Time_Compare (Op1, Op2, Assume_Valid => AV);
12952 -- Res indicates if compare outcome can be compile time determined
f02b8bb8 12953
c800f862
RD
12954 True_Result : Boolean;
12955 False_Result : Boolean;
f02b8bb8 12956
c800f862
RD
12957 begin
12958 case N_Op_Compare (Nkind (N)) is
d26dc4b5
AC
12959 when N_Op_Eq =>
12960 True_Result := Res = EQ;
12961 False_Result := Res = LT or else Res = GT or else Res = NE;
12962
12963 when N_Op_Ge =>
12964 True_Result := Res in Compare_GE;
12965 False_Result := Res = LT;
12966
12967 if Res = LE
12968 and then Constant_Condition_Warnings
12969 and then Comes_From_Source (Original_Node (N))
12970 and then Nkind (Original_Node (N)) = N_Op_Ge
12971 and then not In_Instance
d26dc4b5 12972 and then Is_Integer_Type (Etype (Left_Opnd (N)))
59ae6391 12973 and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
d26dc4b5 12974 then
ed2233dc 12975 Error_Msg_N
324ac540
AC
12976 ("can never be greater than, could replace by ""'=""?c?",
12977 N);
c800f862 12978 Warning_Generated := True;
d26dc4b5 12979 end if;
70482933 12980
d26dc4b5
AC
12981 when N_Op_Gt =>
12982 True_Result := Res = GT;
12983 False_Result := Res in Compare_LE;
12984
12985 when N_Op_Lt =>
12986 True_Result := Res = LT;
12987 False_Result := Res in Compare_GE;
12988
12989 when N_Op_Le =>
12990 True_Result := Res in Compare_LE;
12991 False_Result := Res = GT;
12992
12993 if Res = GE
12994 and then Constant_Condition_Warnings
12995 and then Comes_From_Source (Original_Node (N))
12996 and then Nkind (Original_Node (N)) = N_Op_Le
12997 and then not In_Instance
d26dc4b5 12998 and then Is_Integer_Type (Etype (Left_Opnd (N)))
59ae6391 12999 and then not Has_Warnings_Off (Etype (Left_Opnd (N)))
d26dc4b5 13000 then
ed2233dc 13001 Error_Msg_N
324ac540 13002 ("can never be less than, could replace by ""'=""?c?", N);
c800f862 13003 Warning_Generated := True;
d26dc4b5 13004 end if;
70482933 13005
d26dc4b5
AC
13006 when N_Op_Ne =>
13007 True_Result := Res = NE or else Res = GT or else Res = LT;
13008 False_Result := Res = EQ;
c800f862 13009 end case;
d26dc4b5 13010
c800f862
RD
13011 -- If this is the first iteration, then we actually convert the
13012 -- comparison into True or False, if the result is certain.
d26dc4b5 13013
c800f862
RD
13014 if AV = False then
13015 if True_Result or False_Result then
21791d97 13016 Result := Boolean_Literals (True_Result);
c800f862
RD
13017 Rewrite (N,
13018 Convert_To (Typ,
13019 New_Occurrence_Of (Result, Sloc (N))));
13020 Analyze_And_Resolve (N, Typ);
13021 Warn_On_Known_Condition (N);
13022 return;
13023 end if;
13024
13025 -- If this is the second iteration (AV = True), and the original
e7e4d230
AC
13026 -- node comes from source and we are not in an instance, then give
13027 -- a warning if we know result would be True or False. Note: we
13028 -- know Constant_Condition_Warnings is set if we get here.
c800f862
RD
13029
13030 elsif Comes_From_Source (Original_Node (N))
13031 and then not In_Instance
13032 then
13033 if True_Result then
ed2233dc 13034 Error_Msg_N
324ac540 13035 ("condition can only be False if invalid values present??",
c800f862
RD
13036 N);
13037 elsif False_Result then
ed2233dc 13038 Error_Msg_N
324ac540 13039 ("condition can only be True if invalid values present??",
c800f862
RD
13040 N);
13041 end if;
13042 end if;
13043 end;
13044
13045 -- Skip second iteration if not warning on constant conditions or
e7e4d230
AC
13046 -- if the first iteration already generated a warning of some kind or
13047 -- if we are in any case assuming all values are valid (so that the
13048 -- first iteration took care of the valid case).
c800f862
RD
13049
13050 exit when not Constant_Condition_Warnings;
13051 exit when Warning_Generated;
13052 exit when Assume_No_Invalid_Values;
13053 end loop;
70482933
RK
13054 end Rewrite_Comparison;
13055
fbf5a39b
AC
13056 ----------------------------
13057 -- Safe_In_Place_Array_Op --
13058 ----------------------------
13059
13060 function Safe_In_Place_Array_Op
2e071734
AC
13061 (Lhs : Node_Id;
13062 Op1 : Node_Id;
13063 Op2 : Node_Id) return Boolean
fbf5a39b
AC
13064 is
13065 Target : Entity_Id;
13066
13067 function Is_Safe_Operand (Op : Node_Id) return Boolean;
13068 -- Operand is safe if it cannot overlap part of the target of the
13069 -- operation. If the operand and the target are identical, the operand
13070 -- is safe. The operand can be empty in the case of negation.
13071
13072 function Is_Unaliased (N : Node_Id) return Boolean;
5e1c00fa 13073 -- Check that N is a stand-alone entity
fbf5a39b
AC
13074
13075 ------------------
13076 -- Is_Unaliased --
13077 ------------------
13078
13079 function Is_Unaliased (N : Node_Id) return Boolean is
13080 begin
13081 return
13082 Is_Entity_Name (N)
13083 and then No (Address_Clause (Entity (N)))
13084 and then No (Renamed_Object (Entity (N)));
13085 end Is_Unaliased;
13086
13087 ---------------------
13088 -- Is_Safe_Operand --
13089 ---------------------
13090
13091 function Is_Safe_Operand (Op : Node_Id) return Boolean is
13092 begin
13093 if No (Op) then
13094 return True;
13095
13096 elsif Is_Entity_Name (Op) then
13097 return Is_Unaliased (Op);
13098
303b4d58 13099 elsif Nkind_In (Op, N_Indexed_Component, N_Selected_Component) then
fbf5a39b
AC
13100 return Is_Unaliased (Prefix (Op));
13101
13102 elsif Nkind (Op) = N_Slice then
13103 return
13104 Is_Unaliased (Prefix (Op))
13105 and then Entity (Prefix (Op)) /= Target;
13106
13107 elsif Nkind (Op) = N_Op_Not then
13108 return Is_Safe_Operand (Right_Opnd (Op));
13109
13110 else
13111 return False;
13112 end if;
13113 end Is_Safe_Operand;
13114
b6b5cca8 13115 -- Start of processing for Safe_In_Place_Array_Op
fbf5a39b
AC
13116
13117 begin
685094bf
RD
13118 -- Skip this processing if the component size is different from system
13119 -- storage unit (since at least for NOT this would cause problems).
fbf5a39b 13120
eaa826f8 13121 if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
fbf5a39b
AC
13122 return False;
13123
26bff3d9 13124 -- Cannot do in place stuff on VM_Target since cannot pass addresses
fbf5a39b 13125
26bff3d9 13126 elsif VM_Target /= No_VM then
fbf5a39b
AC
13127 return False;
13128
13129 -- Cannot do in place stuff if non-standard Boolean representation
13130
eaa826f8 13131 elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
fbf5a39b
AC
13132 return False;
13133
13134 elsif not Is_Unaliased (Lhs) then
13135 return False;
e7e4d230 13136
fbf5a39b
AC
13137 else
13138 Target := Entity (Lhs);
e7e4d230 13139 return Is_Safe_Operand (Op1) and then Is_Safe_Operand (Op2);
fbf5a39b
AC
13140 end if;
13141 end Safe_In_Place_Array_Op;
13142
70482933
RK
13143 -----------------------
13144 -- Tagged_Membership --
13145 -----------------------
13146
685094bf
RD
13147 -- There are two different cases to consider depending on whether the right
13148 -- operand is a class-wide type or not. If not we just compare the actual
13149 -- tag of the left expr to the target type tag:
70482933
RK
13150 --
13151 -- Left_Expr.Tag = Right_Type'Tag;
13152 --
685094bf
RD
13153 -- If it is a class-wide type we use the RT function CW_Membership which is
13154 -- usually implemented by looking in the ancestor tables contained in the
13155 -- dispatch table pointed by Left_Expr.Tag for Typ'Tag
70482933 13156
0669bebe
GB
13157 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
13158 -- function IW_Membership which is usually implemented by looking in the
13159 -- table of abstract interface types plus the ancestor table contained in
13160 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
13161
82878151
AC
13162 procedure Tagged_Membership
13163 (N : Node_Id;
13164 SCIL_Node : out Node_Id;
13165 Result : out Node_Id)
13166 is
70482933
RK
13167 Left : constant Node_Id := Left_Opnd (N);
13168 Right : constant Node_Id := Right_Opnd (N);
13169 Loc : constant Source_Ptr := Sloc (N);
13170
38171f43 13171 Full_R_Typ : Entity_Id;
70482933 13172 Left_Type : Entity_Id;
82878151 13173 New_Node : Node_Id;
70482933
RK
13174 Right_Type : Entity_Id;
13175 Obj_Tag : Node_Id;
13176
13177 begin
82878151
AC
13178 SCIL_Node := Empty;
13179
852dba80
AC
13180 -- Handle entities from the limited view
13181
13182 Left_Type := Available_View (Etype (Left));
13183 Right_Type := Available_View (Etype (Right));
70482933 13184
6cce2156
GD
13185 -- In the case where the type is an access type, the test is applied
13186 -- using the designated types (needed in Ada 2012 for implicit anonymous
13187 -- access conversions, for AI05-0149).
13188
13189 if Is_Access_Type (Right_Type) then
13190 Left_Type := Designated_Type (Left_Type);
13191 Right_Type := Designated_Type (Right_Type);
13192 end if;
13193
70482933
RK
13194 if Is_Class_Wide_Type (Left_Type) then
13195 Left_Type := Root_Type (Left_Type);
13196 end if;
13197
38171f43
AC
13198 if Is_Class_Wide_Type (Right_Type) then
13199 Full_R_Typ := Underlying_Type (Root_Type (Right_Type));
13200 else
13201 Full_R_Typ := Underlying_Type (Right_Type);
13202 end if;
13203
70482933
RK
13204 Obj_Tag :=
13205 Make_Selected_Component (Loc,
13206 Prefix => Relocate_Node (Left),
a9d8907c 13207 Selector_Name =>
e4494292 13208 New_Occurrence_Of (First_Tag_Component (Left_Type), Loc));
70482933
RK
13209
13210 if Is_Class_Wide_Type (Right_Type) then
758c442c 13211
0669bebe
GB
13212 -- No need to issue a run-time check if we statically know that the
13213 -- result of this membership test is always true. For example,
13214 -- considering the following declarations:
13215
13216 -- type Iface is interface;
13217 -- type T is tagged null record;
13218 -- type DT is new T and Iface with null record;
13219
13220 -- Obj1 : T;
13221 -- Obj2 : DT;
13222
13223 -- These membership tests are always true:
13224
13225 -- Obj1 in T'Class
13226 -- Obj2 in T'Class;
13227 -- Obj2 in Iface'Class;
13228
13229 -- We do not need to handle cases where the membership is illegal.
13230 -- For example:
13231
13232 -- Obj1 in DT'Class; -- Compile time error
13233 -- Obj1 in Iface'Class; -- Compile time error
13234
13235 if not Is_Class_Wide_Type (Left_Type)
4ac2477e
JM
13236 and then (Is_Ancestor (Etype (Right_Type), Left_Type,
13237 Use_Full_View => True)
533369aa
AC
13238 or else (Is_Interface (Etype (Right_Type))
13239 and then Interface_Present_In_Ancestor
761f7dcb
AC
13240 (Typ => Left_Type,
13241 Iface => Etype (Right_Type))))
0669bebe 13242 then
e4494292 13243 Result := New_Occurrence_Of (Standard_True, Loc);
82878151 13244 return;
0669bebe
GB
13245 end if;
13246
758c442c
GD
13247 -- Ada 2005 (AI-251): Class-wide applied to interfaces
13248
630d30e9
RD
13249 if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
13250
0669bebe 13251 -- Support to: "Iface_CW_Typ in Typ'Class"
630d30e9
RD
13252
13253 or else Is_Interface (Left_Type)
13254 then
dfd99a80
TQ
13255 -- Issue error if IW_Membership operation not available in a
13256 -- configurable run time setting.
13257
13258 if not RTE_Available (RE_IW_Membership) then
b4592168
GD
13259 Error_Msg_CRT
13260 ("dynamic membership test on interface types", N);
82878151
AC
13261 Result := Empty;
13262 return;
dfd99a80
TQ
13263 end if;
13264
82878151 13265 Result :=
758c442c
GD
13266 Make_Function_Call (Loc,
13267 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
13268 Parameter_Associations => New_List (
13269 Make_Attribute_Reference (Loc,
13270 Prefix => Obj_Tag,
13271 Attribute_Name => Name_Address),
e4494292 13272 New_Occurrence_Of (
38171f43 13273 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),
758c442c
GD
13274 Loc)));
13275
13276 -- Ada 95: Normal case
13277
13278 else
82878151
AC
13279 Build_CW_Membership (Loc,
13280 Obj_Tag_Node => Obj_Tag,
13281 Typ_Tag_Node =>
e4494292 13282 New_Occurrence_Of (
38171f43 13283 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc),
82878151
AC
13284 Related_Nod => N,
13285 New_Node => New_Node);
13286
13287 -- Generate the SCIL node for this class-wide membership test.
13288 -- Done here because the previous call to Build_CW_Membership
13289 -- relocates Obj_Tag.
13290
13291 if Generate_SCIL then
13292 SCIL_Node := Make_SCIL_Membership_Test (Sloc (N));
13293 Set_SCIL_Entity (SCIL_Node, Etype (Right_Type));
13294 Set_SCIL_Tag_Value (SCIL_Node, Obj_Tag);
13295 end if;
13296
13297 Result := New_Node;
758c442c
GD
13298 end if;
13299
0669bebe
GB
13300 -- Right_Type is not a class-wide type
13301
70482933 13302 else
0669bebe
GB
13303 -- No need to check the tag of the object if Right_Typ is abstract
13304
13305 if Is_Abstract_Type (Right_Type) then
e4494292 13306 Result := New_Occurrence_Of (Standard_False, Loc);
0669bebe
GB
13307
13308 else
82878151 13309 Result :=
0669bebe
GB
13310 Make_Op_Eq (Loc,
13311 Left_Opnd => Obj_Tag,
13312 Right_Opnd =>
e4494292 13313 New_Occurrence_Of
38171f43 13314 (Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc));
0669bebe 13315 end if;
70482933 13316 end if;
70482933
RK
13317 end Tagged_Membership;
13318
13319 ------------------------------
13320 -- Unary_Op_Validity_Checks --
13321 ------------------------------
13322
13323 procedure Unary_Op_Validity_Checks (N : Node_Id) is
13324 begin
13325 if Validity_Checks_On and Validity_Check_Operands then
13326 Ensure_Valid (Right_Opnd (N));
13327 end if;
13328 end Unary_Op_Validity_Checks;
13329
13330end Exp_Ch4;