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