]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/exp_ch4.adb
[Ada] Variable-sized node types
[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-- --
8d0d46f4 9-- Copyright (C) 1992-2021, 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;
76f9c7f4
BD
29with Einfo; use Einfo;
30with Einfo.Entities; use Einfo.Entities;
31with Einfo.Utils; use Einfo.Utils;
70482933
RK
32with Elists; use Elists;
33with Errout; use Errout;
34with Exp_Aggr; use Exp_Aggr;
0669bebe 35with Exp_Atag; use Exp_Atag;
70482933 36with Exp_Ch3; use Exp_Ch3;
20b5d666 37with Exp_Ch6; use Exp_Ch6;
70482933
RK
38with Exp_Ch7; use Exp_Ch7;
39with Exp_Ch9; use Exp_Ch9;
20b5d666 40with Exp_Disp; use Exp_Disp;
70482933 41with Exp_Fixd; use Exp_Fixd;
437f8c1e 42with Exp_Intr; use Exp_Intr;
70482933
RK
43with Exp_Pakd; use Exp_Pakd;
44with Exp_Tss; use Exp_Tss;
45with Exp_Util; use Exp_Util;
f02b8bb8 46with Freeze; use Freeze;
70482933 47with Inline; use Inline;
26bff3d9 48with Namet; use Namet;
70482933
RK
49with Nlists; use Nlists;
50with Nmake; use Nmake;
51with Opt; use Opt;
25adc5fb 52with Par_SCO; use Par_SCO;
0669bebe
GB
53with Restrict; use Restrict;
54with Rident; use Rident;
70482933
RK
55with Rtsfind; use Rtsfind;
56with Sem; use Sem;
a4100e55 57with Sem_Aux; use Sem_Aux;
70482933 58with Sem_Cat; use Sem_Cat;
5d09245e 59with Sem_Ch3; use Sem_Ch3;
70482933
RK
60with Sem_Ch13; use Sem_Ch13;
61with Sem_Eval; use Sem_Eval;
62with Sem_Res; use Sem_Res;
63with Sem_Type; use Sem_Type;
64with Sem_Util; use Sem_Util;
07fc65c4 65with Sem_Warn; use Sem_Warn;
76f9c7f4
BD
66with Sinfo; use Sinfo;
67with Sinfo.Nodes; use Sinfo.Nodes;
68with Sinfo.Utils; use Sinfo.Utils;
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;
b3889fff 78with Warnsw; use Warnsw;
70482933
RK
79
80package body Exp_Ch4 is
81
15ce9ca2
AC
82 -----------------------
83 -- Local Subprograms --
84 -----------------------
70482933
RK
85
86 procedure Binary_Op_Validity_Checks (N : Node_Id);
87 pragma Inline (Binary_Op_Validity_Checks);
88 -- Performs validity checks for a binary operator
89
fbf5a39b
AC
90 procedure Build_Boolean_Array_Proc_Call
91 (N : Node_Id;
92 Op1 : Node_Id;
93 Op2 : Node_Id);
303b4d58 94 -- If a boolean array assignment can be done in place, build call to
fbf5a39b
AC
95 -- corresponding library procedure.
96
26bff3d9
JM
97 procedure Displace_Allocator_Pointer (N : Node_Id);
98 -- Ada 2005 (AI-251): Subsidiary procedure to Expand_N_Allocator and
99 -- Expand_Allocator_Expression. Allocating class-wide interface objects
100 -- this routine displaces the pointer to the allocated object to reference
101 -- the component referencing the corresponding secondary dispatch table.
102
fbf5a39b
AC
103 procedure Expand_Allocator_Expression (N : Node_Id);
104 -- Subsidiary to Expand_N_Allocator, for the case when the expression
4bfab79a 105 -- is a qualified expression.
fbf5a39b 106
70482933
RK
107 procedure Expand_Array_Comparison (N : Node_Id);
108 -- This routine handles expansion of the comparison operators (N_Op_Lt,
109 -- N_Op_Le, N_Op_Gt, N_Op_Ge) when operating on an array type. The basic
110 -- code for these operators is similar, differing only in the details of
fbf5a39b
AC
111 -- the actual comparison call that is made. Special processing (call a
112 -- run-time routine)
70482933
RK
113
114 function Expand_Array_Equality
115 (Nod : Node_Id;
70482933
RK
116 Lhs : Node_Id;
117 Rhs : Node_Id;
0da2c8ac
AC
118 Bodies : List_Id;
119 Typ : Entity_Id) return Node_Id;
70482933 120 -- Expand an array equality into a call to a function implementing this
685094bf
RD
121 -- equality, and a call to it. Loc is the location for the generated nodes.
122 -- Lhs and Rhs are the array expressions to be compared. Bodies is a list
123 -- on which to attach bodies of local functions that are created in the
124 -- process. It is the responsibility of the caller to insert those bodies
125 -- at the right place. Nod provides the Sloc value for the generated code.
126 -- Normally the types used for the generated equality routine are taken
127 -- from Lhs and Rhs. However, in some situations of generated code, the
128 -- Etype fields of Lhs and Rhs are not set yet. In such cases, Typ supplies
129 -- the type to be used for the formal parameters.
70482933
RK
130
131 procedure Expand_Boolean_Operator (N : Node_Id);
685094bf
RD
132 -- Common expansion processing for Boolean operators (And, Or, Xor) for the
133 -- case of array type arguments.
70482933 134
c7a494c9
AC
135 procedure Expand_Nonbinary_Modular_Op (N : Node_Id);
136 -- When generating C code, convert nonbinary modular arithmetic operations
137 -- into code that relies on the front-end expansion of operator Mod. No
138 -- expansion is performed if N is not a nonbinary modular operand.
05dbb83f 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
d26d790d
AC
155 -- to attach bodies of local functions that are created in the process. It
156 -- is the responsibility of the caller to insert those bodies at the right
157 -- place. Nod provides the Sloc value for generated code. Lhs and Rhs are
158 -- the left and right sides for the comparison, and Typ is the type of the
159 -- 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
2e8ee0a3
EB
179 function Get_Size_For_Range (Lo, Hi : Uint) return Uint;
180 -- Return the size of a small signed integer type covering Lo .. Hi, the
181 -- main goal being to return a size lower than that of standard types.
182
70482933 183 procedure Insert_Dereference_Action (N : Node_Id);
e6f69614
AC
184 -- N is an expression whose type is an access. When the type of the
185 -- associated storage pool is derived from Checked_Pool, generate a
186 -- call to the 'Dereference' primitive operation.
70482933
RK
187
188 function Make_Array_Comparison_Op
2e071734
AC
189 (Typ : Entity_Id;
190 Nod : Node_Id) return Node_Id;
685094bf
RD
191 -- Comparisons between arrays are expanded in line. This function produces
192 -- the body of the implementation of (a > b), where a and b are one-
193 -- dimensional arrays of some discrete type. The original node is then
194 -- expanded into the appropriate call to this function. Nod provides the
195 -- Sloc value for the generated code.
70482933
RK
196
197 function Make_Boolean_Array_Op
2e071734
AC
198 (Typ : Entity_Id;
199 N : Node_Id) return Node_Id;
685094bf
RD
200 -- Boolean operations on boolean arrays are expanded in line. This function
201 -- produce the body for the node N, which is (a and b), (a or b), or (a xor
202 -- b). It is used only the normal case and not the packed case. The type
203 -- involved, Typ, is the Boolean array type, and the logical operations in
204 -- the body are simple boolean operations. Note that Typ is always a
205 -- constrained type (the caller has ensured this by using
206 -- Convert_To_Actual_Subtype if necessary).
70482933 207
b6b5cca8 208 function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean;
a7f1b24f
RD
209 -- For signed arithmetic operations when the current overflow mode is
210 -- MINIMIZED or ELIMINATED, we must call Apply_Arithmetic_Overflow_Checks
211 -- as the first thing we do. We then return. We count on the recursive
212 -- apparatus for overflow checks to call us back with an equivalent
213 -- operation that is in CHECKED mode, avoiding a recursive entry into this
214 -- routine, and that is when we will proceed with the expansion of the
215 -- operator (e.g. converting X+0 to X, or X**2 to X*X). We cannot do
216 -- these optimizations without first making this check, since there may be
217 -- operands further down the tree that are relying on the recursive calls
218 -- triggered by the top level nodes to properly process overflow checking
219 -- and remaining expansion on these nodes. Note that this call back may be
220 -- skipped if the operation is done in Bignum mode but that's fine, since
221 -- the Bignum call takes care of everything.
b6b5cca8 222
6c8e4f7e
EB
223 procedure Narrow_Large_Operation (N : Node_Id);
224 -- Try to compute the result of a large operation in a narrower type than
aaa3a675
GD
225 -- its nominal type. This is mainly aimed at getting rid of operations done
226 -- in Universal_Integer that can be generated for attributes.
6c8e4f7e 227
0580d807
AC
228 procedure Optimize_Length_Comparison (N : Node_Id);
229 -- Given an expression, if it is of the form X'Length op N (or the other
ac8806c4 230 -- way round), where N is known at compile time to be 0 or 1, or something
22b5aff2 231 -- else where the value is known to be nonnegative and in the 32-bit range,
ac8806c4
EB
232 -- and X is a simple entity, and op is a comparison operator, optimizes it
233 -- into a comparison of X'First and X'Last.
0580d807 234
0da343bc
AC
235 procedure Process_If_Case_Statements (N : Node_Id; Stmts : List_Id);
236 -- Inspect and process statement list Stmt of if or case expression N for
937e9676
AC
237 -- transient objects. If such objects are found, the routine generates code
238 -- to clean them up when the context of the expression is evaluated.
239
240 procedure Process_Transient_In_Expression
241 (Obj_Decl : Node_Id;
242 Expr : Node_Id;
243 Stmts : List_Id);
0da343bc
AC
244 -- Subsidiary routine to the expansion of expression_with_actions, if and
245 -- case expressions. Generate all necessary code to finalize a transient
937e9676
AC
246 -- object when the enclosing context is elaborated or evaluated. Obj_Decl
247 -- denotes the declaration of the transient object, which is usually the
248 -- result of a controlled function call. Expr denotes the expression with
249 -- actions, if expression, or case expression node. Stmts denotes the
250 -- statement list which contains Decl, either at the top level or within a
251 -- nested construct.
b2c28399 252
70482933 253 procedure Rewrite_Comparison (N : Node_Id);
20b5d666 254 -- If N is the node for a comparison whose outcome can be determined at
d26dc4b5
AC
255 -- compile time, then the node N can be rewritten with True or False. If
256 -- the outcome cannot be determined at compile time, the call has no
257 -- effect. If N is a type conversion, then this processing is applied to
258 -- its expression. If N is neither comparison nor a type conversion, the
259 -- call has no effect.
70482933 260
82878151
AC
261 procedure Tagged_Membership
262 (N : Node_Id;
263 SCIL_Node : out Node_Id;
264 Result : out Node_Id);
70482933
RK
265 -- Construct the expression corresponding to the tagged membership test.
266 -- Deals with a second operand being (or not) a class-wide type.
267
fbf5a39b 268 function Safe_In_Place_Array_Op
2e071734
AC
269 (Lhs : Node_Id;
270 Op1 : Node_Id;
271 Op2 : Node_Id) return Boolean;
685094bf
RD
272 -- In the context of an assignment, where the right-hand side is a boolean
273 -- operation on arrays, check whether operation can be performed in place.
fbf5a39b 274
70482933
RK
275 procedure Unary_Op_Validity_Checks (N : Node_Id);
276 pragma Inline (Unary_Op_Validity_Checks);
277 -- Performs validity checks for a unary operator
278
279 -------------------------------
280 -- Binary_Op_Validity_Checks --
281 -------------------------------
282
283 procedure Binary_Op_Validity_Checks (N : Node_Id) is
284 begin
285 if Validity_Checks_On and Validity_Check_Operands then
286 Ensure_Valid (Left_Opnd (N));
287 Ensure_Valid (Right_Opnd (N));
288 end if;
289 end Binary_Op_Validity_Checks;
290
fbf5a39b
AC
291 ------------------------------------
292 -- Build_Boolean_Array_Proc_Call --
293 ------------------------------------
294
295 procedure Build_Boolean_Array_Proc_Call
296 (N : Node_Id;
297 Op1 : Node_Id;
298 Op2 : Node_Id)
299 is
300 Loc : constant Source_Ptr := Sloc (N);
301 Kind : constant Node_Kind := Nkind (Expression (N));
302 Target : constant Node_Id :=
303 Make_Attribute_Reference (Loc,
304 Prefix => Name (N),
305 Attribute_Name => Name_Address);
306
bed8af19 307 Arg1 : Node_Id := Op1;
fbf5a39b
AC
308 Arg2 : Node_Id := Op2;
309 Call_Node : Node_Id;
310 Proc_Name : Entity_Id;
311
312 begin
313 if Kind = N_Op_Not then
314 if Nkind (Op1) in N_Binary_Op then
315
5e1c00fa 316 -- Use negated version of the binary operators
fbf5a39b
AC
317
318 if Nkind (Op1) = N_Op_And then
319 Proc_Name := RTE (RE_Vector_Nand);
320
321 elsif Nkind (Op1) = N_Op_Or then
322 Proc_Name := RTE (RE_Vector_Nor);
323
324 else pragma Assert (Nkind (Op1) = N_Op_Xor);
325 Proc_Name := RTE (RE_Vector_Xor);
326 end if;
327
328 Call_Node :=
329 Make_Procedure_Call_Statement (Loc,
330 Name => New_Occurrence_Of (Proc_Name, Loc),
331
332 Parameter_Associations => New_List (
333 Target,
334 Make_Attribute_Reference (Loc,
335 Prefix => Left_Opnd (Op1),
336 Attribute_Name => Name_Address),
337
338 Make_Attribute_Reference (Loc,
339 Prefix => Right_Opnd (Op1),
340 Attribute_Name => Name_Address),
341
342 Make_Attribute_Reference (Loc,
343 Prefix => Left_Opnd (Op1),
344 Attribute_Name => Name_Length)));
345
346 else
347 Proc_Name := RTE (RE_Vector_Not);
348
349 Call_Node :=
350 Make_Procedure_Call_Statement (Loc,
351 Name => New_Occurrence_Of (Proc_Name, Loc),
352 Parameter_Associations => New_List (
353 Target,
354
355 Make_Attribute_Reference (Loc,
356 Prefix => Op1,
357 Attribute_Name => Name_Address),
358
359 Make_Attribute_Reference (Loc,
360 Prefix => Op1,
361 Attribute_Name => Name_Length)));
362 end if;
363
364 else
365 -- We use the following equivalences:
366
367 -- (not X) or (not Y) = not (X and Y) = Nand (X, Y)
368 -- (not X) and (not Y) = not (X or Y) = Nor (X, Y)
369 -- (not X) xor (not Y) = X xor Y
370 -- X xor (not Y) = not (X xor Y) = Nxor (X, Y)
371
372 if Nkind (Op1) = N_Op_Not then
bed8af19
AC
373 Arg1 := Right_Opnd (Op1);
374 Arg2 := Right_Opnd (Op2);
533369aa 375
fbf5a39b
AC
376 if Kind = N_Op_And then
377 Proc_Name := RTE (RE_Vector_Nor);
fbf5a39b
AC
378 elsif Kind = N_Op_Or then
379 Proc_Name := RTE (RE_Vector_Nand);
fbf5a39b
AC
380 else
381 Proc_Name := RTE (RE_Vector_Xor);
382 end if;
383
384 else
385 if Kind = N_Op_And then
386 Proc_Name := RTE (RE_Vector_And);
fbf5a39b
AC
387 elsif Kind = N_Op_Or then
388 Proc_Name := RTE (RE_Vector_Or);
fbf5a39b
AC
389 elsif Nkind (Op2) = N_Op_Not then
390 Proc_Name := RTE (RE_Vector_Nxor);
391 Arg2 := Right_Opnd (Op2);
fbf5a39b
AC
392 else
393 Proc_Name := RTE (RE_Vector_Xor);
394 end if;
395 end if;
396
397 Call_Node :=
398 Make_Procedure_Call_Statement (Loc,
399 Name => New_Occurrence_Of (Proc_Name, Loc),
400 Parameter_Associations => New_List (
401 Target,
955871d3
AC
402 Make_Attribute_Reference (Loc,
403 Prefix => Arg1,
404 Attribute_Name => Name_Address),
405 Make_Attribute_Reference (Loc,
406 Prefix => Arg2,
407 Attribute_Name => Name_Address),
408 Make_Attribute_Reference (Loc,
a8ef12e5 409 Prefix => Arg1,
955871d3 410 Attribute_Name => Name_Length)));
fbf5a39b
AC
411 end if;
412
413 Rewrite (N, Call_Node);
414 Analyze (N);
415
416 exception
417 when RE_Not_Available =>
418 return;
419 end Build_Boolean_Array_Proc_Call;
420
eedc5882
HK
421 -----------------------
422 -- Build_Eq_Call --
423 -----------------------
424
425 function Build_Eq_Call
426 (Typ : Entity_Id;
427 Loc : Source_Ptr;
428 Lhs : Node_Id;
429 Rhs : Node_Id) return Node_Id
430 is
431 Prim : Node_Id;
432 Prim_E : Elmt_Id;
433
434 begin
435 Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
436 while Present (Prim_E) loop
437 Prim := Node (Prim_E);
438
439 -- Locate primitive equality with the right signature
440
441 if Chars (Prim) = Name_Op_Eq
442 and then Etype (First_Formal (Prim)) =
443 Etype (Next_Formal (First_Formal (Prim)))
444 and then Etype (Prim) = Standard_Boolean
445 then
446 if Is_Abstract_Subprogram (Prim) then
447 return
448 Make_Raise_Program_Error (Loc,
449 Reason => PE_Explicit_Raise);
450
451 else
452 return
453 Make_Function_Call (Loc,
454 Name => New_Occurrence_Of (Prim, Loc),
455 Parameter_Associations => New_List (Lhs, Rhs));
456 end if;
457 end if;
458
459 Next_Elmt (Prim_E);
460 end loop;
461
462 -- If not found, predefined operation will be used
463
464 return Empty;
465 end Build_Eq_Call;
466
26bff3d9
JM
467 --------------------------------
468 -- Displace_Allocator_Pointer --
469 --------------------------------
470
471 procedure Displace_Allocator_Pointer (N : Node_Id) is
472 Loc : constant Source_Ptr := Sloc (N);
473 Orig_Node : constant Node_Id := Original_Node (N);
474 Dtyp : Entity_Id;
475 Etyp : Entity_Id;
476 PtrT : Entity_Id;
477
478 begin
303b4d58
AC
479 -- Do nothing in case of VM targets: the virtual machine will handle
480 -- interfaces directly.
481
1f110335 482 if not Tagged_Type_Expansion then
303b4d58
AC
483 return;
484 end if;
485
26bff3d9
JM
486 pragma Assert (Nkind (N) = N_Identifier
487 and then Nkind (Orig_Node) = N_Allocator);
488
489 PtrT := Etype (Orig_Node);
d6a24cdb 490 Dtyp := Available_View (Designated_Type (PtrT));
26bff3d9
JM
491 Etyp := Etype (Expression (Orig_Node));
492
533369aa
AC
493 if Is_Class_Wide_Type (Dtyp) and then Is_Interface (Dtyp) then
494
26bff3d9
JM
495 -- If the type of the allocator expression is not an interface type
496 -- we can generate code to reference the record component containing
497 -- the pointer to the secondary dispatch table.
498
499 if not Is_Interface (Etyp) then
500 declare
501 Saved_Typ : constant Entity_Id := Etype (Orig_Node);
502
503 begin
504 -- 1) Get access to the allocated object
505
506 Rewrite (N,
5972791c 507 Make_Explicit_Dereference (Loc, Relocate_Node (N)));
26bff3d9
JM
508 Set_Etype (N, Etyp);
509 Set_Analyzed (N);
510
511 -- 2) Add the conversion to displace the pointer to reference
512 -- the secondary dispatch table.
513
514 Rewrite (N, Convert_To (Dtyp, Relocate_Node (N)));
515 Analyze_And_Resolve (N, Dtyp);
516
517 -- 3) The 'access to the secondary dispatch table will be used
518 -- as the value returned by the allocator.
519
520 Rewrite (N,
521 Make_Attribute_Reference (Loc,
522 Prefix => Relocate_Node (N),
523 Attribute_Name => Name_Access));
524 Set_Etype (N, Saved_Typ);
525 Set_Analyzed (N);
526 end;
527
528 -- If the type of the allocator expression is an interface type we
529 -- generate a run-time call to displace "this" to reference the
530 -- component containing the pointer to the secondary dispatch table
531 -- or else raise Constraint_Error if the actual object does not
533369aa 532 -- implement the target interface. This case corresponds to the
26bff3d9
JM
533 -- following example:
534
8fc789c8 535 -- function Op (Obj : Iface_1'Class) return access Iface_2'Class is
26bff3d9
JM
536 -- begin
537 -- return new Iface_2'Class'(Obj);
538 -- end Op;
539
540 else
541 Rewrite (N,
542 Unchecked_Convert_To (PtrT,
543 Make_Function_Call (Loc,
e4494292 544 Name => New_Occurrence_Of (RTE (RE_Displace), Loc),
26bff3d9
JM
545 Parameter_Associations => New_List (
546 Unchecked_Convert_To (RTE (RE_Address),
547 Relocate_Node (N)),
548
549 New_Occurrence_Of
550 (Elists.Node
551 (First_Elmt
552 (Access_Disp_Table (Etype (Base_Type (Dtyp))))),
553 Loc)))));
554 Analyze_And_Resolve (N, PtrT);
555 end if;
556 end if;
557 end Displace_Allocator_Pointer;
558
fbf5a39b
AC
559 ---------------------------------
560 -- Expand_Allocator_Expression --
561 ---------------------------------
562
563 procedure Expand_Allocator_Expression (N : Node_Id) is
f02b8bb8
RD
564 Loc : constant Source_Ptr := Sloc (N);
565 Exp : constant Node_Id := Expression (Expression (N));
f02b8bb8
RD
566 PtrT : constant Entity_Id := Etype (N);
567 DesigT : constant Entity_Id := Designated_Type (PtrT);
26bff3d9
JM
568
569 procedure Apply_Accessibility_Check
570 (Ref : Node_Id;
571 Built_In_Place : Boolean := False);
572 -- Ada 2005 (AI-344): For an allocator with a class-wide designated
685094bf
RD
573 -- type, generate an accessibility check to verify that the level of the
574 -- type of the created object is not deeper than the level of the access
50878404 575 -- type. If the type of the qualified expression is class-wide, then
685094bf
RD
576 -- always generate the check (except in the case where it is known to be
577 -- unnecessary, see comment below). Otherwise, only generate the check
578 -- if the level of the qualified expression type is statically deeper
579 -- than the access type.
580 --
581 -- Although the static accessibility will generally have been performed
582 -- as a legality check, it won't have been done in cases where the
583 -- allocator appears in generic body, so a run-time check is needed in
584 -- general. One special case is when the access type is declared in the
585 -- same scope as the class-wide allocator, in which case the check can
586 -- never fail, so it need not be generated.
587 --
588 -- As an open issue, there seem to be cases where the static level
589 -- associated with the class-wide object's underlying type is not
590 -- sufficient to perform the proper accessibility check, such as for
591 -- allocators in nested subprograms or accept statements initialized by
592 -- class-wide formals when the actual originates outside at a deeper
593 -- static level. The nested subprogram case might require passing
594 -- accessibility levels along with class-wide parameters, and the task
595 -- case seems to be an actual gap in the language rules that needs to
596 -- be fixed by the ARG. ???
26bff3d9
JM
597
598 -------------------------------
599 -- Apply_Accessibility_Check --
600 -------------------------------
601
602 procedure Apply_Accessibility_Check
603 (Ref : Node_Id;
604 Built_In_Place : Boolean := False)
605 is
a98838ff
HK
606 Pool_Id : constant Entity_Id := Associated_Storage_Pool (PtrT);
607 Cond : Node_Id;
608 Fin_Call : Node_Id;
609 Free_Stmt : Node_Id;
610 Obj_Ref : Node_Id;
611 Stmts : List_Id;
26bff3d9
JM
612
613 begin
0791fbe9 614 if Ada_Version >= Ada_2005
26bff3d9 615 and then Is_Class_Wide_Type (DesigT)
535a8637 616 and then Tagged_Type_Expansion
3217f71e 617 and then not Scope_Suppress.Suppress (Accessibility_Check)
26bff3d9
JM
618 and then
619 (Type_Access_Level (Etype (Exp)) > Type_Access_Level (PtrT)
620 or else
621 (Is_Class_Wide_Type (Etype (Exp))
622 and then Scope (PtrT) /= Current_Scope))
623 then
e761d11c 624 -- If the allocator was built in place, Ref is already a reference
26bff3d9 625 -- to the access object initialized to the result of the allocator
e761d11c
AC
626 -- (see Exp_Ch6.Make_Build_In_Place_Call_In_Allocator). We call
627 -- Remove_Side_Effects for cases where the build-in-place call may
628 -- still be the prefix of the reference (to avoid generating
629 -- duplicate calls). Otherwise, it is the entity associated with
630 -- the object containing the address of the allocated object.
26bff3d9
JM
631
632 if Built_In_Place then
e761d11c 633 Remove_Side_Effects (Ref);
a98838ff 634 Obj_Ref := New_Copy_Tree (Ref);
26bff3d9 635 else
e4494292 636 Obj_Ref := New_Occurrence_Of (Ref, Loc);
50878404
AC
637 end if;
638
b6c8e5be
AC
639 -- For access to interface types we must generate code to displace
640 -- the pointer to the base of the object since the subsequent code
641 -- references components located in the TSD of the object (which
642 -- is associated with the primary dispatch table --see a-tags.ads)
643 -- and also generates code invoking Free, which requires also a
644 -- reference to the base of the unallocated object.
645
cc6f5d75 646 if Is_Interface (DesigT) and then Tagged_Type_Expansion then
b6c8e5be
AC
647 Obj_Ref :=
648 Unchecked_Convert_To (Etype (Obj_Ref),
649 Make_Function_Call (Loc,
662c2ad4
RD
650 Name =>
651 New_Occurrence_Of (RTE (RE_Base_Address), Loc),
b6c8e5be
AC
652 Parameter_Associations => New_List (
653 Unchecked_Convert_To (RTE (RE_Address),
654 New_Copy_Tree (Obj_Ref)))));
655 end if;
656
50878404
AC
657 -- Step 1: Create the object clean up code
658
659 Stmts := New_List;
660
a98838ff
HK
661 -- Deallocate the object if the accessibility check fails. This
662 -- is done only on targets or profiles that support deallocation.
663
664 -- Free (Obj_Ref);
665
666 if RTE_Available (RE_Free) then
667 Free_Stmt := Make_Free_Statement (Loc, New_Copy_Tree (Obj_Ref));
668 Set_Storage_Pool (Free_Stmt, Pool_Id);
669
670 Append_To (Stmts, Free_Stmt);
671
672 -- The target or profile cannot deallocate objects
673
674 else
675 Free_Stmt := Empty;
676 end if;
677
678 -- Finalize the object if applicable. Generate:
a530b8bb
AC
679
680 -- [Deep_]Finalize (Obj_Ref.all);
681
7cc7f3aa
PMR
682 if Needs_Finalization (DesigT)
683 and then not No_Heap_Finalization (PtrT)
684 then
a98838ff 685 Fin_Call :=
cc6f5d75
AC
686 Make_Final_Call
687 (Obj_Ref =>
688 Make_Explicit_Dereference (Loc, New_Copy (Obj_Ref)),
689 Typ => DesigT);
a98838ff 690
2168d7cc
AC
691 -- Guard against a missing [Deep_]Finalize when the designated
692 -- type was not properly frozen.
693
694 if No (Fin_Call) then
695 Fin_Call := Make_Null_Statement (Loc);
696 end if;
697
a98838ff
HK
698 -- When the target or profile supports deallocation, wrap the
699 -- finalization call in a block to ensure proper deallocation
700 -- even if finalization fails. Generate:
701
702 -- begin
703 -- <Fin_Call>
704 -- exception
705 -- when others =>
706 -- <Free_Stmt>
707 -- raise;
708 -- end;
709
710 if Present (Free_Stmt) then
711 Fin_Call :=
712 Make_Block_Statement (Loc,
713 Handled_Statement_Sequence =>
714 Make_Handled_Sequence_Of_Statements (Loc,
715 Statements => New_List (Fin_Call),
716
717 Exception_Handlers => New_List (
718 Make_Exception_Handler (Loc,
719 Exception_Choices => New_List (
720 Make_Others_Choice (Loc)),
a98838ff
HK
721 Statements => New_List (
722 New_Copy_Tree (Free_Stmt),
723 Make_Raise_Statement (Loc))))));
724 end if;
725
726 Prepend_To (Stmts, Fin_Call);
f46faa08
AC
727 end if;
728
50878404
AC
729 -- Signal the accessibility failure through a Program_Error
730
731 Append_To (Stmts,
732 Make_Raise_Program_Error (Loc,
a1198973 733 Reason => PE_Accessibility_Check_Failed));
50878404
AC
734
735 -- Step 2: Create the accessibility comparison
736
737 -- Generate:
738 -- Ref'Tag
739
b6c8e5be
AC
740 Obj_Ref :=
741 Make_Attribute_Reference (Loc,
742 Prefix => Obj_Ref,
743 Attribute_Name => Name_Tag);
f46faa08 744
50878404
AC
745 -- For tagged types, determine the accessibility level by looking
746 -- at the type specific data of the dispatch table. Generate:
747
748 -- Type_Specific_Data (Address (Ref'Tag)).Access_Level
749
f46faa08 750 if Tagged_Type_Expansion then
50878404 751 Cond := Build_Get_Access_Level (Loc, Obj_Ref);
f46faa08 752
50878404
AC
753 -- Use a runtime call to determine the accessibility level when
754 -- compiling on virtual machine targets. Generate:
f46faa08 755
50878404 756 -- Get_Access_Level (Ref'Tag)
f46faa08
AC
757
758 else
50878404
AC
759 Cond :=
760 Make_Function_Call (Loc,
761 Name =>
e4494292 762 New_Occurrence_Of (RTE (RE_Get_Access_Level), Loc),
50878404 763 Parameter_Associations => New_List (Obj_Ref));
26bff3d9
JM
764 end if;
765
50878404
AC
766 Cond :=
767 Make_Op_Gt (Loc,
768 Left_Opnd => Cond,
769 Right_Opnd =>
770 Make_Integer_Literal (Loc, Type_Access_Level (PtrT)));
771
772 -- Due to the complexity and side effects of the check, utilize an
773 -- if statement instead of the regular Program_Error circuitry.
774
26bff3d9 775 Insert_Action (N,
8b1011c0 776 Make_Implicit_If_Statement (N,
50878404
AC
777 Condition => Cond,
778 Then_Statements => Stmts));
26bff3d9
JM
779 end if;
780 end Apply_Accessibility_Check;
781
782 -- Local variables
783
df3e68b1
HK
784 Indic : constant Node_Id := Subtype_Mark (Expression (N));
785 T : constant Entity_Id := Entity (Indic);
2168d7cc 786 Adj_Call : Node_Id;
4bfab79a 787 Aggr_In_Place : Boolean;
df3e68b1
HK
788 Node : Node_Id;
789 Tag_Assign : Node_Id;
790 Temp : Entity_Id;
791 Temp_Decl : Node_Id;
fbf5a39b 792
d26dc4b5
AC
793 TagT : Entity_Id := Empty;
794 -- Type used as source for tag assignment
795
796 TagR : Node_Id := Empty;
797 -- Target reference for tag assignment
798
26bff3d9
JM
799 -- Start of processing for Expand_Allocator_Expression
800
fbf5a39b 801 begin
3bfb3c03
JM
802 -- Handle call to C++ constructor
803
804 if Is_CPP_Constructor_Call (Exp) then
805 Make_CPP_Constructor_Call_In_Allocator
806 (Allocator => N,
807 Function_Call => Exp);
808 return;
809 end if;
810
4bfab79a
EB
811 -- If we have:
812 -- type A is access T1;
813 -- X : A := new T2'(...);
814 -- T1 and T2 can be different subtypes, and we might need to check
815 -- both constraints. First check against the type of the qualified
816 -- expression.
817
818 Apply_Constraint_Check (Exp, T, No_Sliding => True);
819
820 Apply_Predicate_Check (Exp, T);
821
66e97274
JS
822 -- Check that any anonymous access discriminants are suitable
823 -- for use in an allocator.
824
825 -- Note: This check is performed here instead of during analysis so that
826 -- we can check against the fully resolved etype of Exp.
827
828 if Is_Entity_Name (Exp)
829 and then Has_Anonymous_Access_Discriminant (Etype (Exp))
830 and then Static_Accessibility_Level (Exp, Object_Decl_Level)
831 > Static_Accessibility_Level (N, Object_Decl_Level)
832 then
833 -- A dynamic check and a warning are generated when we are within
834 -- an instance.
835
836 if In_Instance then
837 Insert_Action (N,
838 Make_Raise_Program_Error (Loc,
839 Reason => PE_Accessibility_Check_Failed));
840
841 Error_Msg_N ("anonymous access discriminant is too deep for use"
842 & " in allocator<<", N);
843 Error_Msg_N ("\Program_Error [<<", N);
844
845 -- Otherwise, make the error static
846
847 else
848 Error_Msg_N ("anonymous access discriminant is too deep for use"
849 & " in allocator", N);
850 end if;
851 end if;
852
4bfab79a
EB
853 if Do_Range_Check (Exp) then
854 Generate_Range_Check (Exp, T, CE_Range_Check_Failed);
855 end if;
856
857 -- A check is also needed in cases where the designated subtype is
858 -- constrained and differs from the subtype given in the qualified
859 -- expression. Note that the check on the qualified expression does
860 -- not allow sliding, but this check does (a relaxation from Ada 83).
861
862 if Is_Constrained (DesigT)
863 and then not Subtypes_Statically_Match (T, DesigT)
864 then
865 Apply_Constraint_Check (Exp, DesigT, No_Sliding => False);
866
867 Apply_Predicate_Check (Exp, DesigT);
868
869 if Do_Range_Check (Exp) then
870 Generate_Range_Check (Exp, DesigT, CE_Range_Check_Failed);
871 end if;
872 end if;
873
874 if Nkind (Exp) = N_Raise_Constraint_Error then
875 Rewrite (N, New_Copy (Exp));
876 Set_Etype (N, PtrT);
877 return;
878 end if;
879
4bfab79a
EB
880 Aggr_In_Place := Is_Delayed_Aggregate (Exp);
881
f6194278 882 -- Case of tagged type or type requiring finalization
63585f75
SB
883
884 if Is_Tagged_Type (T) or else Needs_Finalization (T) then
fadcf313 885
685094bf
RD
886 -- Ada 2005 (AI-318-02): If the initialization expression is a call
887 -- to a build-in-place function, then access to the allocated object
d4dfb005 888 -- must be passed to the function.
20b5d666 889
d4dfb005 890 if Is_Build_In_Place_Function_Call (Exp) then
20b5d666 891 Make_Build_In_Place_Call_In_Allocator (N, Exp);
26bff3d9
JM
892 Apply_Accessibility_Check (N, Built_In_Place => True);
893 return;
4ac62786
AC
894
895 -- Ada 2005 (AI-318-02): Specialization of the previous case for
896 -- expressions containing a build-in-place function call whose
897 -- returned object covers interface types, and Expr has calls to
898 -- Ada.Tags.Displace to displace the pointer to the returned build-
899 -- in-place object to reference the secondary dispatch table of a
900 -- covered interface type.
901
d4dfb005 902 elsif Present (Unqual_BIP_Iface_Function_Call (Exp)) then
4ac62786
AC
903 Make_Build_In_Place_Iface_Call_In_Allocator (N, Exp);
904 Apply_Accessibility_Check (N, Built_In_Place => True);
905 return;
20b5d666
JM
906 end if;
907
ca5af305
AC
908 -- Actions inserted before:
909 -- Temp : constant ptr_T := new T'(Expression);
910 -- Temp._tag = T'tag; -- when not class-wide
911 -- [Deep_]Adjust (Temp.all);
fbf5a39b 912
ca5af305 913 -- We analyze by hand the new internal allocator to avoid any
6b6041ec 914 -- recursion and inappropriate call to Initialize.
7324bf49 915
20b5d666
JM
916 -- We don't want to remove side effects when the expression must be
917 -- built in place. In the case of a build-in-place function call,
918 -- that could lead to a duplication of the call, which was already
919 -- substituted for the allocator.
920
26bff3d9 921 if not Aggr_In_Place then
fbf5a39b
AC
922 Remove_Side_Effects (Exp);
923 end if;
924
e86a3a7e 925 Temp := Make_Temporary (Loc, 'P', N);
fbf5a39b
AC
926
927 -- For a class wide allocation generate the following code:
928
929 -- type Equiv_Record is record ... end record;
930 -- implicit subtype CW is <Class_Wide_Subytpe>;
931 -- temp : PtrT := new CW'(CW!(expr));
932
933 if Is_Class_Wide_Type (T) then
934 Expand_Subtype_From_Expr (Empty, T, Indic, Exp);
935
26bff3d9
JM
936 -- Ada 2005 (AI-251): If the expression is a class-wide interface
937 -- object we generate code to move up "this" to reference the
938 -- base of the object before allocating the new object.
939
940 -- Note that Exp'Address is recursively expanded into a call
941 -- to Base_Address (Exp.Tag)
942
943 if Is_Class_Wide_Type (Etype (Exp))
944 and then Is_Interface (Etype (Exp))
1f110335 945 and then Tagged_Type_Expansion
26bff3d9
JM
946 then
947 Set_Expression
948 (Expression (N),
949 Unchecked_Convert_To (Entity (Indic),
950 Make_Explicit_Dereference (Loc,
951 Unchecked_Convert_To (RTE (RE_Tag_Ptr),
952 Make_Attribute_Reference (Loc,
953 Prefix => Exp,
954 Attribute_Name => Name_Address)))));
26bff3d9
JM
955 else
956 Set_Expression
957 (Expression (N),
958 Unchecked_Convert_To (Entity (Indic), Exp));
959 end if;
fbf5a39b
AC
960
961 Analyze_And_Resolve (Expression (N), Entity (Indic));
962 end if;
963
df3e68b1 964 -- Processing for allocators returning non-interface types
fbf5a39b 965
26bff3d9
JM
966 if not Is_Interface (Directly_Designated_Type (PtrT)) then
967 if Aggr_In_Place then
df3e68b1 968 Temp_Decl :=
26bff3d9
JM
969 Make_Object_Declaration (Loc,
970 Defining_Identifier => Temp,
e4494292 971 Object_Definition => New_Occurrence_Of (PtrT, Loc),
26bff3d9
JM
972 Expression =>
973 Make_Allocator (Loc,
df3e68b1 974 Expression =>
e4494292 975 New_Occurrence_Of (Etype (Exp), Loc)));
fbf5a39b 976
fad0600d
AC
977 -- Copy the Comes_From_Source flag for the allocator we just
978 -- built, since logically this allocator is a replacement of
979 -- the original allocator node. This is for proper handling of
980 -- restriction No_Implicit_Heap_Allocations.
981
73642e68
PT
982 Preserve_Comes_From_Source
983 (Expression (Temp_Decl), N);
fbf5a39b 984
df3e68b1
HK
985 Set_No_Initialization (Expression (Temp_Decl));
986 Insert_Action (N, Temp_Decl);
fbf5a39b 987
ca5af305 988 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 989 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
fad0600d 990
26bff3d9
JM
991 else
992 Node := Relocate_Node (N);
993 Set_Analyzed (Node);
df3e68b1
HK
994
995 Temp_Decl :=
26bff3d9
JM
996 Make_Object_Declaration (Loc,
997 Defining_Identifier => Temp,
998 Constant_Present => True,
e4494292 999 Object_Definition => New_Occurrence_Of (PtrT, Loc),
df3e68b1
HK
1000 Expression => Node);
1001
1002 Insert_Action (N, Temp_Decl);
ca5af305 1003 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
fbf5a39b
AC
1004 end if;
1005
26bff3d9
JM
1006 -- Ada 2005 (AI-251): Handle allocators whose designated type is an
1007 -- interface type. In this case we use the type of the qualified
1008 -- expression to allocate the object.
1009
fbf5a39b 1010 else
26bff3d9 1011 declare
191fcb3a 1012 Def_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
26bff3d9 1013 New_Decl : Node_Id;
fbf5a39b 1014
26bff3d9
JM
1015 begin
1016 New_Decl :=
1017 Make_Full_Type_Declaration (Loc,
1018 Defining_Identifier => Def_Id,
cc6f5d75 1019 Type_Definition =>
26bff3d9
JM
1020 Make_Access_To_Object_Definition (Loc,
1021 All_Present => True,
1022 Null_Exclusion_Present => False,
0929eaeb
AC
1023 Constant_Present =>
1024 Is_Access_Constant (Etype (N)),
26bff3d9 1025 Subtype_Indication =>
e4494292 1026 New_Occurrence_Of (Etype (Exp), Loc)));
26bff3d9
JM
1027
1028 Insert_Action (N, New_Decl);
1029
df3e68b1
HK
1030 -- Inherit the allocation-related attributes from the original
1031 -- access type.
26bff3d9 1032
24d4b3d5
AC
1033 Set_Finalization_Master
1034 (Def_Id, Finalization_Master (PtrT));
df3e68b1 1035
24d4b3d5
AC
1036 Set_Associated_Storage_Pool
1037 (Def_Id, Associated_Storage_Pool (PtrT));
758c442c 1038
26bff3d9
JM
1039 -- Declare the object using the previous type declaration
1040
1041 if Aggr_In_Place then
df3e68b1 1042 Temp_Decl :=
26bff3d9
JM
1043 Make_Object_Declaration (Loc,
1044 Defining_Identifier => Temp,
e4494292 1045 Object_Definition => New_Occurrence_Of (Def_Id, Loc),
26bff3d9
JM
1046 Expression =>
1047 Make_Allocator (Loc,
e4494292 1048 New_Occurrence_Of (Etype (Exp), Loc)));
26bff3d9 1049
fad0600d
AC
1050 -- Copy the Comes_From_Source flag for the allocator we just
1051 -- built, since logically this allocator is a replacement of
1052 -- the original allocator node. This is for proper handling
1053 -- of restriction No_Implicit_Heap_Allocations.
1054
26bff3d9 1055 Set_Comes_From_Source
df3e68b1 1056 (Expression (Temp_Decl), Comes_From_Source (N));
26bff3d9 1057
df3e68b1
HK
1058 Set_No_Initialization (Expression (Temp_Decl));
1059 Insert_Action (N, Temp_Decl);
26bff3d9 1060
ca5af305 1061 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 1062 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
26bff3d9 1063
26bff3d9
JM
1064 else
1065 Node := Relocate_Node (N);
1066 Set_Analyzed (Node);
df3e68b1
HK
1067
1068 Temp_Decl :=
26bff3d9
JM
1069 Make_Object_Declaration (Loc,
1070 Defining_Identifier => Temp,
1071 Constant_Present => True,
e4494292 1072 Object_Definition => New_Occurrence_Of (Def_Id, Loc),
df3e68b1
HK
1073 Expression => Node);
1074
1075 Insert_Action (N, Temp_Decl);
ca5af305 1076 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
26bff3d9
JM
1077 end if;
1078
1079 -- Generate an additional object containing the address of the
1080 -- returned object. The type of this second object declaration
685094bf
RD
1081 -- is the correct type required for the common processing that
1082 -- is still performed by this subprogram. The displacement of
1083 -- this pointer to reference the component associated with the
1084 -- interface type will be done at the end of common processing.
26bff3d9
JM
1085
1086 New_Decl :=
1087 Make_Object_Declaration (Loc,
243cae0a 1088 Defining_Identifier => Make_Temporary (Loc, 'P'),
e4494292 1089 Object_Definition => New_Occurrence_Of (PtrT, Loc),
243cae0a 1090 Expression =>
df3e68b1 1091 Unchecked_Convert_To (PtrT,
e4494292 1092 New_Occurrence_Of (Temp, Loc)));
26bff3d9
JM
1093
1094 Insert_Action (N, New_Decl);
1095
df3e68b1
HK
1096 Temp_Decl := New_Decl;
1097 Temp := Defining_Identifier (New_Decl);
26bff3d9 1098 end;
758c442c
GD
1099 end if;
1100
26bff3d9
JM
1101 -- Generate the tag assignment
1102
535a8637 1103 -- Suppress the tag assignment for VM targets because VM tags are
26bff3d9
JM
1104 -- represented implicitly in objects.
1105
1f110335 1106 if not Tagged_Type_Expansion then
26bff3d9 1107 null;
fbf5a39b 1108
26bff3d9
JM
1109 -- Ada 2005 (AI-251): Suppress the tag assignment with class-wide
1110 -- interface objects because in this case the tag does not change.
d26dc4b5 1111
26bff3d9
JM
1112 elsif Is_Interface (Directly_Designated_Type (Etype (N))) then
1113 pragma Assert (Is_Class_Wide_Type
1114 (Directly_Designated_Type (Etype (N))));
d26dc4b5
AC
1115 null;
1116
1117 elsif Is_Tagged_Type (T) and then not Is_Class_Wide_Type (T) then
1118 TagT := T;
f715a5bd
EB
1119 TagR :=
1120 Make_Explicit_Dereference (Loc,
1121 Prefix => New_Occurrence_Of (Temp, Loc));
d26dc4b5
AC
1122
1123 elsif Is_Private_Type (T)
1124 and then Is_Tagged_Type (Underlying_Type (T))
fbf5a39b 1125 then
d26dc4b5 1126 TagT := Underlying_Type (T);
dfd99a80
TQ
1127 TagR :=
1128 Unchecked_Convert_To (Underlying_Type (T),
1129 Make_Explicit_Dereference (Loc,
e4494292 1130 Prefix => New_Occurrence_Of (Temp, Loc)));
d26dc4b5
AC
1131 end if;
1132
1133 if Present (TagT) then
38171f43
AC
1134 declare
1135 Full_T : constant Entity_Id := Underlying_Type (TagT);
e4494292 1136
38171f43
AC
1137 begin
1138 Tag_Assign :=
1139 Make_Assignment_Statement (Loc,
cc6f5d75 1140 Name =>
38171f43 1141 Make_Selected_Component (Loc,
cc6f5d75 1142 Prefix => TagR,
38171f43 1143 Selector_Name =>
e4494292
RD
1144 New_Occurrence_Of
1145 (First_Tag_Component (Full_T), Loc)),
1146
38171f43
AC
1147 Expression =>
1148 Unchecked_Convert_To (RTE (RE_Tag),
e4494292 1149 New_Occurrence_Of
38171f43
AC
1150 (Elists.Node
1151 (First_Elmt (Access_Disp_Table (Full_T))), Loc)));
1152 end;
fbf5a39b
AC
1153
1154 -- The previous assignment has to be done in any case
1155
1156 Set_Assignment_OK (Name (Tag_Assign));
1157 Insert_Action (N, Tag_Assign);
fbf5a39b
AC
1158 end if;
1159
18431dc5
AC
1160 -- Generate an Adjust call if the object will be moved. In Ada 2005,
1161 -- the object may be inherently limited, in which case there is no
1162 -- Adjust procedure, and the object is built in place. In Ada 95, the
1163 -- object can be limited but not inherently limited if this allocator
1164 -- came from a return statement (we're allocating the result on the
1165 -- secondary stack). In that case, the object will be moved, so we do
3a248f7c
BD
1166 -- want to Adjust. However, if it's a nonlimited build-in-place
1167 -- function call, Adjust is not wanted.
18431dc5
AC
1168
1169 if Needs_Finalization (DesigT)
1170 and then Needs_Finalization (T)
1171 and then not Aggr_In_Place
1172 and then not Is_Limited_View (T)
3a248f7c
BD
1173 and then not Alloc_For_BIP_Return (N)
1174 and then not Is_Build_In_Place_Function_Call (Expression (N))
18431dc5
AC
1175 then
1176 -- An unchecked conversion is needed in the classwide case because
1177 -- the designated type can be an ancestor of the subtype mark of
1178 -- the allocator.
df3e68b1 1179
2168d7cc 1180 Adj_Call :=
18431dc5
AC
1181 Make_Adjust_Call
1182 (Obj_Ref =>
1183 Unchecked_Convert_To (T,
1184 Make_Explicit_Dereference (Loc,
1185 Prefix => New_Occurrence_Of (Temp, Loc))),
2168d7cc
AC
1186 Typ => T);
1187
1188 if Present (Adj_Call) then
1189 Insert_Action (N, Adj_Call);
1190 end if;
18431dc5 1191 end if;
fbf5a39b 1192
18431dc5
AC
1193 -- Note: the accessibility check must be inserted after the call to
1194 -- [Deep_]Adjust to ensure proper completion of the assignment.
fbf5a39b 1195
18431dc5 1196 Apply_Accessibility_Check (Temp);
fbf5a39b 1197
e4494292 1198 Rewrite (N, New_Occurrence_Of (Temp, Loc));
fbf5a39b
AC
1199 Analyze_And_Resolve (N, PtrT);
1200
685094bf
RD
1201 -- Ada 2005 (AI-251): Displace the pointer to reference the record
1202 -- component containing the secondary dispatch table of the interface
1203 -- type.
26bff3d9
JM
1204
1205 if Is_Interface (Directly_Designated_Type (PtrT)) then
1206 Displace_Allocator_Pointer (N);
1207 end if;
1208
dfbc6cbe
AC
1209 -- Always force the generation of a temporary for aggregates when
1210 -- generating C code, to simplify the work in the code generator.
1211
1212 elsif Aggr_In_Place
c63a2ad6 1213 or else (Modify_Tree_For_C and then Nkind (Exp) = N_Aggregate)
dfbc6cbe 1214 then
e86a3a7e 1215 Temp := Make_Temporary (Loc, 'P', N);
df3e68b1 1216 Temp_Decl :=
fbf5a39b
AC
1217 Make_Object_Declaration (Loc,
1218 Defining_Identifier => Temp,
e4494292 1219 Object_Definition => New_Occurrence_Of (PtrT, Loc),
df3e68b1
HK
1220 Expression =>
1221 Make_Allocator (Loc,
e4494292 1222 Expression => New_Occurrence_Of (Etype (Exp), Loc)));
fbf5a39b 1223
fad0600d
AC
1224 -- Copy the Comes_From_Source flag for the allocator we just built,
1225 -- since logically this allocator is a replacement of the original
1226 -- allocator node. This is for proper handling of restriction
1227 -- No_Implicit_Heap_Allocations.
1228
fbf5a39b 1229 Set_Comes_From_Source
df3e68b1
HK
1230 (Expression (Temp_Decl), Comes_From_Source (N));
1231
1232 Set_No_Initialization (Expression (Temp_Decl));
1233 Insert_Action (N, Temp_Decl);
1234
ca5af305 1235 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 1236 Convert_Aggr_In_Allocator (N, Temp_Decl, Exp);
fbf5a39b 1237
e4494292 1238 Rewrite (N, New_Occurrence_Of (Temp, Loc));
fbf5a39b
AC
1239 Analyze_And_Resolve (N, PtrT);
1240
533369aa 1241 elsif Is_Access_Type (T) and then Can_Never_Be_Null (T) then
51e4c4b9
AC
1242 Install_Null_Excluding_Check (Exp);
1243
f02b8bb8 1244 elsif Is_Access_Type (DesigT)
fbf5a39b
AC
1245 and then Nkind (Exp) = N_Allocator
1246 and then Nkind (Expression (Exp)) /= N_Qualified_Expression
1247 then
0da2c8ac 1248 -- Apply constraint to designated subtype indication
fbf5a39b 1249
cc6f5d75
AC
1250 Apply_Constraint_Check
1251 (Expression (Exp), Designated_Type (DesigT), No_Sliding => True);
fbf5a39b
AC
1252
1253 if Nkind (Expression (Exp)) = N_Raise_Constraint_Error then
1254
1255 -- Propagate constraint_error to enclosing allocator
1256
1257 Rewrite (Exp, New_Copy (Expression (Exp)));
1258 end if;
1df4f514 1259
fbf5a39b 1260 else
14f0f659
AC
1261 Build_Allocate_Deallocate_Proc (N, True);
1262
685094bf
RD
1263 -- For an access to unconstrained packed array, GIGI needs to see an
1264 -- expression with a constrained subtype in order to compute the
1265 -- proper size for the allocator.
f02b8bb8 1266
bfe5f951 1267 if Is_Packed_Array (T)
f02b8bb8 1268 and then not Is_Constrained (T)
f02b8bb8
RD
1269 then
1270 declare
191fcb3a 1271 ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
f02b8bb8
RD
1272 Internal_Exp : constant Node_Id := Relocate_Node (Exp);
1273 begin
1274 Insert_Action (Exp,
1275 Make_Subtype_Declaration (Loc,
1276 Defining_Identifier => ConstrT,
25ebc085
AC
1277 Subtype_Indication =>
1278 Make_Subtype_From_Expr (Internal_Exp, T)));
f02b8bb8
RD
1279 Freeze_Itype (ConstrT, Exp);
1280 Rewrite (Exp, OK_Convert_To (ConstrT, Internal_Exp));
1281 end;
fbf5a39b 1282 end if;
f02b8bb8 1283
685094bf
RD
1284 -- Ada 2005 (AI-318-02): If the initialization expression is a call
1285 -- to a build-in-place function, then access to the allocated object
d4dfb005 1286 -- must be passed to the function.
20b5d666 1287
d4dfb005 1288 if Is_Build_In_Place_Function_Call (Exp) then
20b5d666
JM
1289 Make_Build_In_Place_Call_In_Allocator (N, Exp);
1290 end if;
fbf5a39b
AC
1291 end if;
1292
1293 exception
1294 when RE_Not_Available =>
1295 return;
1296 end Expand_Allocator_Expression;
1297
70482933
RK
1298 -----------------------------
1299 -- Expand_Array_Comparison --
1300 -----------------------------
1301
685094bf
RD
1302 -- Expansion is only required in the case of array types. For the unpacked
1303 -- case, an appropriate runtime routine is called. For packed cases, and
1304 -- also in some other cases where a runtime routine cannot be called, the
1305 -- form of the expansion is:
70482933
RK
1306
1307 -- [body for greater_nn; boolean_expression]
1308
1309 -- The body is built by Make_Array_Comparison_Op, and the form of the
1310 -- Boolean expression depends on the operator involved.
1311
1312 procedure Expand_Array_Comparison (N : Node_Id) is
1313 Loc : constant Source_Ptr := Sloc (N);
1314 Op1 : Node_Id := Left_Opnd (N);
1315 Op2 : Node_Id := Right_Opnd (N);
1316 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
fbf5a39b 1317 Ctyp : constant Entity_Id := Component_Type (Typ1);
70482933
RK
1318
1319 Expr : Node_Id;
1320 Func_Body : Node_Id;
1321 Func_Name : Entity_Id;
1322
fbf5a39b
AC
1323 Comp : RE_Id;
1324
9bc43c53
AC
1325 Byte_Addressable : constant Boolean := System_Storage_Unit = Byte'Size;
1326 -- True for byte addressable target
91b1417d 1327
fbf5a39b 1328 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean;
685094bf
RD
1329 -- Returns True if the length of the given operand is known to be less
1330 -- than 4. Returns False if this length is known to be four or greater
1331 -- or is not known at compile time.
fbf5a39b
AC
1332
1333 ------------------------
1334 -- Length_Less_Than_4 --
1335 ------------------------
1336
1337 function Length_Less_Than_4 (Opnd : Node_Id) return Boolean is
1338 Otyp : constant Entity_Id := Etype (Opnd);
1339
1340 begin
1341 if Ekind (Otyp) = E_String_Literal_Subtype then
1342 return String_Literal_Length (Otyp) < 4;
1343
1344 else
1345 declare
1346 Ityp : constant Entity_Id := Etype (First_Index (Otyp));
1347 Lo : constant Node_Id := Type_Low_Bound (Ityp);
1348 Hi : constant Node_Id := Type_High_Bound (Ityp);
1349 Lov : Uint;
1350 Hiv : Uint;
1351
1352 begin
1353 if Compile_Time_Known_Value (Lo) then
1354 Lov := Expr_Value (Lo);
1355 else
1356 return False;
1357 end if;
1358
1359 if Compile_Time_Known_Value (Hi) then
1360 Hiv := Expr_Value (Hi);
1361 else
1362 return False;
1363 end if;
1364
1365 return Hiv < Lov + 3;
1366 end;
1367 end if;
1368 end Length_Less_Than_4;
1369
1370 -- Start of processing for Expand_Array_Comparison
1371
70482933 1372 begin
fbf5a39b
AC
1373 -- Deal first with unpacked case, where we can call a runtime routine
1374 -- except that we avoid this for targets for which are not addressable
535a8637 1375 -- by bytes.
fbf5a39b 1376
cbe3b8d4 1377 if not Is_Bit_Packed_Array (Typ1) and then Byte_Addressable then
fbf5a39b
AC
1378 -- The call we generate is:
1379
1380 -- Compare_Array_xn[_Unaligned]
1381 -- (left'address, right'address, left'length, right'length) <op> 0
1382
1383 -- x = U for unsigned, S for signed
a5476382 1384 -- n = 8,16,32,64,128 for component size
fbf5a39b
AC
1385 -- Add _Unaligned if length < 4 and component size is 8.
1386 -- <op> is the standard comparison operator
1387
1388 if Component_Size (Typ1) = 8 then
1389 if Length_Less_Than_4 (Op1)
1390 or else
1391 Length_Less_Than_4 (Op2)
1392 then
1393 if Is_Unsigned_Type (Ctyp) then
1394 Comp := RE_Compare_Array_U8_Unaligned;
1395 else
1396 Comp := RE_Compare_Array_S8_Unaligned;
1397 end if;
1398
1399 else
1400 if Is_Unsigned_Type (Ctyp) then
1401 Comp := RE_Compare_Array_U8;
1402 else
1403 Comp := RE_Compare_Array_S8;
1404 end if;
1405 end if;
1406
1407 elsif Component_Size (Typ1) = 16 then
1408 if Is_Unsigned_Type (Ctyp) then
1409 Comp := RE_Compare_Array_U16;
1410 else
1411 Comp := RE_Compare_Array_S16;
1412 end if;
1413
1414 elsif Component_Size (Typ1) = 32 then
1415 if Is_Unsigned_Type (Ctyp) then
1416 Comp := RE_Compare_Array_U32;
1417 else
1418 Comp := RE_Compare_Array_S32;
1419 end if;
1420
a5476382 1421 elsif Component_Size (Typ1) = 64 then
fbf5a39b
AC
1422 if Is_Unsigned_Type (Ctyp) then
1423 Comp := RE_Compare_Array_U64;
1424 else
1425 Comp := RE_Compare_Array_S64;
1426 end if;
a5476382
EB
1427
1428 else pragma Assert (Component_Size (Typ1) = 128);
1429 if Is_Unsigned_Type (Ctyp) then
1430 Comp := RE_Compare_Array_U128;
1431 else
1432 Comp := RE_Compare_Array_S128;
1433 end if;
fbf5a39b
AC
1434 end if;
1435
9fe696a3 1436 if RTE_Available (Comp) then
fbf5a39b 1437
9fe696a3 1438 -- Expand to a call only if the runtime function is available,
744c73a5 1439 -- otherwise fall back to inline code.
fbf5a39b 1440
9fe696a3
AC
1441 Remove_Side_Effects (Op1, Name_Req => True);
1442 Remove_Side_Effects (Op2, Name_Req => True);
fbf5a39b 1443
9fe696a3
AC
1444 Rewrite (Op1,
1445 Make_Function_Call (Sloc (Op1),
1446 Name => New_Occurrence_Of (RTE (Comp), Loc),
fbf5a39b 1447
9fe696a3
AC
1448 Parameter_Associations => New_List (
1449 Make_Attribute_Reference (Loc,
1450 Prefix => Relocate_Node (Op1),
1451 Attribute_Name => Name_Address),
fbf5a39b 1452
9fe696a3
AC
1453 Make_Attribute_Reference (Loc,
1454 Prefix => Relocate_Node (Op2),
1455 Attribute_Name => Name_Address),
fbf5a39b 1456
9fe696a3
AC
1457 Make_Attribute_Reference (Loc,
1458 Prefix => Relocate_Node (Op1),
1459 Attribute_Name => Name_Length),
fbf5a39b 1460
9fe696a3
AC
1461 Make_Attribute_Reference (Loc,
1462 Prefix => Relocate_Node (Op2),
1463 Attribute_Name => Name_Length))));
1464
1465 Rewrite (Op2,
1466 Make_Integer_Literal (Sloc (Op2),
1467 Intval => Uint_0));
1468
1469 Analyze_And_Resolve (Op1, Standard_Integer);
1470 Analyze_And_Resolve (Op2, Standard_Integer);
1471 return;
1472 end if;
fbf5a39b
AC
1473 end if;
1474
1475 -- Cases where we cannot make runtime call
1476
70482933
RK
1477 -- For (a <= b) we convert to not (a > b)
1478
1479 if Chars (N) = Name_Op_Le then
1480 Rewrite (N,
1481 Make_Op_Not (Loc,
1482 Right_Opnd =>
1483 Make_Op_Gt (Loc,
1484 Left_Opnd => Op1,
1485 Right_Opnd => Op2)));
1486 Analyze_And_Resolve (N, Standard_Boolean);
1487 return;
1488
1489 -- For < the Boolean expression is
1490 -- greater__nn (op2, op1)
1491
1492 elsif Chars (N) = Name_Op_Lt then
1493 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1494
1495 -- Switch operands
1496
1497 Op1 := Right_Opnd (N);
1498 Op2 := Left_Opnd (N);
1499
1500 -- For (a >= b) we convert to not (a < b)
1501
1502 elsif Chars (N) = Name_Op_Ge then
1503 Rewrite (N,
1504 Make_Op_Not (Loc,
1505 Right_Opnd =>
1506 Make_Op_Lt (Loc,
1507 Left_Opnd => Op1,
1508 Right_Opnd => Op2)));
1509 Analyze_And_Resolve (N, Standard_Boolean);
1510 return;
1511
1512 -- For > the Boolean expression is
1513 -- greater__nn (op1, op2)
1514
1515 else
1516 pragma Assert (Chars (N) = Name_Op_Gt);
1517 Func_Body := Make_Array_Comparison_Op (Typ1, N);
1518 end if;
1519
1520 Func_Name := Defining_Unit_Name (Specification (Func_Body));
1521 Expr :=
1522 Make_Function_Call (Loc,
e4494292 1523 Name => New_Occurrence_Of (Func_Name, Loc),
70482933
RK
1524 Parameter_Associations => New_List (Op1, Op2));
1525
1526 Insert_Action (N, Func_Body);
1527 Rewrite (N, Expr);
1528 Analyze_And_Resolve (N, Standard_Boolean);
70482933
RK
1529 end Expand_Array_Comparison;
1530
1531 ---------------------------
1532 -- Expand_Array_Equality --
1533 ---------------------------
1534
685094bf
RD
1535 -- Expand an equality function for multi-dimensional arrays. Here is an
1536 -- example of such a function for Nb_Dimension = 2
70482933 1537
0da2c8ac 1538 -- function Enn (A : atyp; B : btyp) return boolean is
70482933 1539 -- begin
fbf5a39b
AC
1540 -- if (A'length (1) = 0 or else A'length (2) = 0)
1541 -- and then
1542 -- (B'length (1) = 0 or else B'length (2) = 0)
1543 -- then
1544 -- return True; -- RM 4.5.2(22)
1545 -- end if;
0da2c8ac 1546
fbf5a39b
AC
1547 -- if A'length (1) /= B'length (1)
1548 -- or else
1549 -- A'length (2) /= B'length (2)
1550 -- then
1551 -- return False; -- RM 4.5.2(23)
1552 -- end if;
0da2c8ac 1553
fbf5a39b 1554 -- declare
523456db
AC
1555 -- A1 : Index_T1 := A'first (1);
1556 -- B1 : Index_T1 := B'first (1);
fbf5a39b 1557 -- begin
523456db 1558 -- loop
fbf5a39b 1559 -- declare
523456db
AC
1560 -- A2 : Index_T2 := A'first (2);
1561 -- B2 : Index_T2 := B'first (2);
fbf5a39b 1562 -- begin
523456db 1563 -- loop
fbf5a39b
AC
1564 -- if A (A1, A2) /= B (B1, B2) then
1565 -- return False;
70482933 1566 -- end if;
0da2c8ac 1567
523456db
AC
1568 -- exit when A2 = A'last (2);
1569 -- A2 := Index_T2'succ (A2);
0da2c8ac 1570 -- B2 := Index_T2'succ (B2);
70482933 1571 -- end loop;
fbf5a39b 1572 -- end;
0da2c8ac 1573
523456db
AC
1574 -- exit when A1 = A'last (1);
1575 -- A1 := Index_T1'succ (A1);
0da2c8ac 1576 -- B1 := Index_T1'succ (B1);
70482933 1577 -- end loop;
fbf5a39b 1578 -- end;
0da2c8ac 1579
70482933
RK
1580 -- return true;
1581 -- end Enn;
1582
685094bf
RD
1583 -- Note on the formal types used (atyp and btyp). If either of the arrays
1584 -- is of a private type, we use the underlying type, and do an unchecked
1585 -- conversion of the actual. If either of the arrays has a bound depending
1586 -- on a discriminant, then we use the base type since otherwise we have an
1587 -- escaped discriminant in the function.
0da2c8ac 1588
685094bf
RD
1589 -- If both arrays are constrained and have the same bounds, we can generate
1590 -- a loop with an explicit iteration scheme using a 'Range attribute over
1591 -- the first array.
523456db 1592
70482933
RK
1593 function Expand_Array_Equality
1594 (Nod : Node_Id;
70482933
RK
1595 Lhs : Node_Id;
1596 Rhs : Node_Id;
0da2c8ac
AC
1597 Bodies : List_Id;
1598 Typ : Entity_Id) return Node_Id
70482933
RK
1599 is
1600 Loc : constant Source_Ptr := Sloc (Nod);
fbf5a39b
AC
1601 Decls : constant List_Id := New_List;
1602 Index_List1 : constant List_Id := New_List;
1603 Index_List2 : constant List_Id := New_List;
1604
1dd3915b 1605 First_Idx : Node_Id;
fbf5a39b
AC
1606 Formals : List_Id;
1607 Func_Name : Entity_Id;
1608 Func_Body : Node_Id;
70482933
RK
1609
1610 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
1611 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
1612
0da2c8ac
AC
1613 Ltyp : Entity_Id;
1614 Rtyp : Entity_Id;
1615 -- The parameter types to be used for the formals
1616
1dd3915b
EB
1617 New_Lhs : Node_Id;
1618 New_Rhs : Node_Id;
1619 -- The LHS and RHS converted to the parameter types
1620
fbf5a39b
AC
1621 function Arr_Attr
1622 (Arr : Entity_Id;
1623 Nam : Name_Id;
2e071734 1624 Num : Int) return Node_Id;
5e1c00fa 1625 -- This builds the attribute reference Arr'Nam (Expr)
fbf5a39b 1626
70482933 1627 function Component_Equality (Typ : Entity_Id) return Node_Id;
685094bf 1628 -- Create one statement to compare corresponding components, designated
3b42c566 1629 -- by a full set of indexes.
70482933 1630
0da2c8ac 1631 function Get_Arg_Type (N : Node_Id) return Entity_Id;
685094bf
RD
1632 -- Given one of the arguments, computes the appropriate type to be used
1633 -- for that argument in the corresponding function formal
0da2c8ac 1634
fbf5a39b 1635 function Handle_One_Dimension
70482933 1636 (N : Int;
2e071734 1637 Index : Node_Id) return Node_Id;
0da2c8ac 1638 -- This procedure returns the following code
fbf5a39b
AC
1639 --
1640 -- declare
523456db 1641 -- Bn : Index_T := B'First (N);
fbf5a39b 1642 -- begin
523456db 1643 -- loop
fbf5a39b 1644 -- xxx
523456db
AC
1645 -- exit when An = A'Last (N);
1646 -- An := Index_T'Succ (An)
0da2c8ac 1647 -- Bn := Index_T'Succ (Bn)
fbf5a39b
AC
1648 -- end loop;
1649 -- end;
1650 --
3b42c566 1651 -- If both indexes are constrained and identical, the procedure
523456db
AC
1652 -- returns a simpler loop:
1653 --
1654 -- for An in A'Range (N) loop
1655 -- xxx
1656 -- end loop
0da2c8ac 1657 --
523456db 1658 -- N is the dimension for which we are generating a loop. Index is the
685094bf
RD
1659 -- N'th index node, whose Etype is Index_Type_n in the above code. The
1660 -- xxx statement is either the loop or declare for the next dimension
1661 -- or if this is the last dimension the comparison of corresponding
1662 -- components of the arrays.
fbf5a39b 1663 --
685094bf 1664 -- The actual way the code works is to return the comparison of
a90bd866 1665 -- corresponding components for the N+1 call. That's neater.
fbf5a39b
AC
1666
1667 function Test_Empty_Arrays return Node_Id;
1668 -- This function constructs the test for both arrays being empty
1669 -- (A'length (1) = 0 or else A'length (2) = 0 or else ...)
1670 -- and then
1671 -- (B'length (1) = 0 or else B'length (2) = 0 or else ...)
1672
1673 function Test_Lengths_Correspond return Node_Id;
685094bf
RD
1674 -- This function constructs the test for arrays having different lengths
1675 -- in at least one index position, in which case the resulting code is:
fbf5a39b
AC
1676
1677 -- A'length (1) /= B'length (1)
1678 -- or else
1679 -- A'length (2) /= B'length (2)
1680 -- or else
1681 -- ...
1682
1683 --------------
1684 -- Arr_Attr --
1685 --------------
1686
1687 function Arr_Attr
1688 (Arr : Entity_Id;
1689 Nam : Name_Id;
2e071734 1690 Num : Int) return Node_Id
fbf5a39b
AC
1691 is
1692 begin
1693 return
1694 Make_Attribute_Reference (Loc,
cc6f5d75
AC
1695 Attribute_Name => Nam,
1696 Prefix => New_Occurrence_Of (Arr, Loc),
1697 Expressions => New_List (Make_Integer_Literal (Loc, Num)));
fbf5a39b 1698 end Arr_Attr;
70482933
RK
1699
1700 ------------------------
1701 -- Component_Equality --
1702 ------------------------
1703
1704 function Component_Equality (Typ : Entity_Id) return Node_Id is
1705 Test : Node_Id;
1706 L, R : Node_Id;
1707
1708 begin
1709 -- if a(i1...) /= b(j1...) then return false; end if;
1710
1711 L :=
1712 Make_Indexed_Component (Loc,
7675ad4f 1713 Prefix => Make_Identifier (Loc, Chars (A)),
70482933
RK
1714 Expressions => Index_List1);
1715
1716 R :=
1717 Make_Indexed_Component (Loc,
7675ad4f 1718 Prefix => Make_Identifier (Loc, Chars (B)),
70482933
RK
1719 Expressions => Index_List2);
1720
1721 Test := Expand_Composite_Equality
1722 (Nod, Component_Type (Typ), L, R, Decls);
1723
a9d8907c
JM
1724 -- If some (sub)component is an unchecked_union, the whole operation
1725 -- will raise program error.
8aceda64
AC
1726
1727 if Nkind (Test) = N_Raise_Program_Error then
a9d8907c
JM
1728
1729 -- This node is going to be inserted at a location where a
685094bf
RD
1730 -- statement is expected: clear its Etype so analysis will set
1731 -- it to the expected Standard_Void_Type.
a9d8907c
JM
1732
1733 Set_Etype (Test, Empty);
8aceda64
AC
1734 return Test;
1735
1736 else
1737 return
1738 Make_Implicit_If_Statement (Nod,
cc6f5d75 1739 Condition => Make_Op_Not (Loc, Right_Opnd => Test),
8aceda64 1740 Then_Statements => New_List (
d766cee3 1741 Make_Simple_Return_Statement (Loc,
8aceda64
AC
1742 Expression => New_Occurrence_Of (Standard_False, Loc))));
1743 end if;
70482933
RK
1744 end Component_Equality;
1745
0da2c8ac
AC
1746 ------------------
1747 -- Get_Arg_Type --
1748 ------------------
1749
1750 function Get_Arg_Type (N : Node_Id) return Entity_Id is
1751 T : Entity_Id;
1752 X : Node_Id;
1753
1754 begin
1755 T := Etype (N);
1756
1757 if No (T) then
1758 return Typ;
1759
1760 else
1761 T := Underlying_Type (T);
1762
1763 X := First_Index (T);
1764 while Present (X) loop
761f7dcb
AC
1765 if Denotes_Discriminant (Type_Low_Bound (Etype (X)))
1766 or else
1767 Denotes_Discriminant (Type_High_Bound (Etype (X)))
0da2c8ac
AC
1768 then
1769 T := Base_Type (T);
1770 exit;
1771 end if;
1772
1773 Next_Index (X);
1774 end loop;
1775
1776 return T;
1777 end if;
1778 end Get_Arg_Type;
1779
fbf5a39b
AC
1780 --------------------------
1781 -- Handle_One_Dimension --
1782 ---------------------------
70482933 1783
fbf5a39b 1784 function Handle_One_Dimension
70482933 1785 (N : Int;
2e071734 1786 Index : Node_Id) return Node_Id
70482933 1787 is
0da2c8ac 1788 Need_Separate_Indexes : constant Boolean :=
761f7dcb 1789 Ltyp /= Rtyp or else not Is_Constrained (Ltyp);
0da2c8ac 1790 -- If the index types are identical, and we are working with
685094bf
RD
1791 -- constrained types, then we can use the same index for both
1792 -- of the arrays.
0da2c8ac 1793
191fcb3a 1794 An : constant Entity_Id := Make_Temporary (Loc, 'A');
0da2c8ac
AC
1795
1796 Bn : Entity_Id;
1797 Index_T : Entity_Id;
1798 Stm_List : List_Id;
1799 Loop_Stm : Node_Id;
70482933
RK
1800
1801 begin
0da2c8ac
AC
1802 if N > Number_Dimensions (Ltyp) then
1803 return Component_Equality (Ltyp);
fbf5a39b 1804 end if;
70482933 1805
0da2c8ac
AC
1806 -- Case where we generate a loop
1807
1808 Index_T := Base_Type (Etype (Index));
1809
1810 if Need_Separate_Indexes then
191fcb3a 1811 Bn := Make_Temporary (Loc, 'B');
0da2c8ac
AC
1812 else
1813 Bn := An;
1814 end if;
70482933 1815
e4494292
RD
1816 Append (New_Occurrence_Of (An, Loc), Index_List1);
1817 Append (New_Occurrence_Of (Bn, Loc), Index_List2);
70482933 1818
0da2c8ac
AC
1819 Stm_List := New_List (
1820 Handle_One_Dimension (N + 1, Next_Index (Index)));
70482933 1821
0da2c8ac 1822 if Need_Separate_Indexes then
a9d8907c 1823
3b42c566 1824 -- Generate guard for loop, followed by increments of indexes
523456db
AC
1825
1826 Append_To (Stm_List,
1827 Make_Exit_Statement (Loc,
1828 Condition =>
1829 Make_Op_Eq (Loc,
cc6f5d75 1830 Left_Opnd => New_Occurrence_Of (An, Loc),
523456db
AC
1831 Right_Opnd => Arr_Attr (A, Name_Last, N))));
1832
1833 Append_To (Stm_List,
1834 Make_Assignment_Statement (Loc,
e4494292 1835 Name => New_Occurrence_Of (An, Loc),
523456db
AC
1836 Expression =>
1837 Make_Attribute_Reference (Loc,
e4494292 1838 Prefix => New_Occurrence_Of (Index_T, Loc),
523456db 1839 Attribute_Name => Name_Succ,
e4494292
RD
1840 Expressions => New_List (
1841 New_Occurrence_Of (An, Loc)))));
523456db 1842
0da2c8ac
AC
1843 Append_To (Stm_List,
1844 Make_Assignment_Statement (Loc,
e4494292 1845 Name => New_Occurrence_Of (Bn, Loc),
0da2c8ac
AC
1846 Expression =>
1847 Make_Attribute_Reference (Loc,
e4494292 1848 Prefix => New_Occurrence_Of (Index_T, Loc),
0da2c8ac 1849 Attribute_Name => Name_Succ,
e4494292
RD
1850 Expressions => New_List (
1851 New_Occurrence_Of (Bn, Loc)))));
0da2c8ac
AC
1852 end if;
1853
a9d8907c
JM
1854 -- If separate indexes, we need a declare block for An and Bn, and a
1855 -- loop without an iteration scheme.
0da2c8ac
AC
1856
1857 if Need_Separate_Indexes then
523456db
AC
1858 Loop_Stm :=
1859 Make_Implicit_Loop_Statement (Nod, Statements => Stm_List);
1860
0da2c8ac
AC
1861 return
1862 Make_Block_Statement (Loc,
1863 Declarations => New_List (
523456db
AC
1864 Make_Object_Declaration (Loc,
1865 Defining_Identifier => An,
e4494292 1866 Object_Definition => New_Occurrence_Of (Index_T, Loc),
523456db
AC
1867 Expression => Arr_Attr (A, Name_First, N)),
1868
0da2c8ac
AC
1869 Make_Object_Declaration (Loc,
1870 Defining_Identifier => Bn,
e4494292 1871 Object_Definition => New_Occurrence_Of (Index_T, Loc),
0da2c8ac 1872 Expression => Arr_Attr (B, Name_First, N))),
523456db 1873
0da2c8ac
AC
1874 Handled_Statement_Sequence =>
1875 Make_Handled_Sequence_Of_Statements (Loc,
1876 Statements => New_List (Loop_Stm)));
1877
523456db 1878 -- If no separate indexes, return loop statement with explicit
31fde973 1879 -- iteration scheme on its own.
0da2c8ac
AC
1880
1881 else
523456db
AC
1882 Loop_Stm :=
1883 Make_Implicit_Loop_Statement (Nod,
1884 Statements => Stm_List,
1885 Iteration_Scheme =>
1886 Make_Iteration_Scheme (Loc,
1887 Loop_Parameter_Specification =>
1888 Make_Loop_Parameter_Specification (Loc,
1889 Defining_Identifier => An,
1890 Discrete_Subtype_Definition =>
1891 Arr_Attr (A, Name_Range, N))));
0da2c8ac
AC
1892 return Loop_Stm;
1893 end if;
fbf5a39b
AC
1894 end Handle_One_Dimension;
1895
1896 -----------------------
1897 -- Test_Empty_Arrays --
1898 -----------------------
1899
1900 function Test_Empty_Arrays return Node_Id is
1901 Alist : Node_Id;
1902 Blist : Node_Id;
1903
1904 Atest : Node_Id;
1905 Btest : Node_Id;
70482933 1906
fbf5a39b
AC
1907 begin
1908 Alist := Empty;
1909 Blist := Empty;
0da2c8ac 1910 for J in 1 .. Number_Dimensions (Ltyp) loop
fbf5a39b
AC
1911 Atest :=
1912 Make_Op_Eq (Loc,
1913 Left_Opnd => Arr_Attr (A, Name_Length, J),
1914 Right_Opnd => Make_Integer_Literal (Loc, 0));
1915
1916 Btest :=
1917 Make_Op_Eq (Loc,
1918 Left_Opnd => Arr_Attr (B, Name_Length, J),
1919 Right_Opnd => Make_Integer_Literal (Loc, 0));
1920
1921 if No (Alist) then
1922 Alist := Atest;
1923 Blist := Btest;
70482933 1924
fbf5a39b
AC
1925 else
1926 Alist :=
1927 Make_Or_Else (Loc,
1928 Left_Opnd => Relocate_Node (Alist),
1929 Right_Opnd => Atest);
1930
1931 Blist :=
1932 Make_Or_Else (Loc,
1933 Left_Opnd => Relocate_Node (Blist),
1934 Right_Opnd => Btest);
1935 end if;
1936 end loop;
70482933 1937
fbf5a39b
AC
1938 return
1939 Make_And_Then (Loc,
1940 Left_Opnd => Alist,
1941 Right_Opnd => Blist);
1942 end Test_Empty_Arrays;
70482933 1943
fbf5a39b
AC
1944 -----------------------------
1945 -- Test_Lengths_Correspond --
1946 -----------------------------
70482933 1947
fbf5a39b
AC
1948 function Test_Lengths_Correspond return Node_Id is
1949 Result : Node_Id;
1950 Rtest : Node_Id;
1951
1952 begin
1953 Result := Empty;
0da2c8ac 1954 for J in 1 .. Number_Dimensions (Ltyp) loop
fbf5a39b
AC
1955 Rtest :=
1956 Make_Op_Ne (Loc,
1957 Left_Opnd => Arr_Attr (A, Name_Length, J),
1958 Right_Opnd => Arr_Attr (B, Name_Length, J));
1959
1960 if No (Result) then
1961 Result := Rtest;
1962 else
1963 Result :=
1964 Make_Or_Else (Loc,
1965 Left_Opnd => Relocate_Node (Result),
1966 Right_Opnd => Rtest);
1967 end if;
1968 end loop;
1969
1970 return Result;
1971 end Test_Lengths_Correspond;
70482933
RK
1972
1973 -- Start of processing for Expand_Array_Equality
1974
1975 begin
0da2c8ac
AC
1976 Ltyp := Get_Arg_Type (Lhs);
1977 Rtyp := Get_Arg_Type (Rhs);
1978
685094bf
RD
1979 -- For now, if the argument types are not the same, go to the base type,
1980 -- since the code assumes that the formals have the same type. This is
1981 -- fixable in future ???
0da2c8ac
AC
1982
1983 if Ltyp /= Rtyp then
1984 Ltyp := Base_Type (Ltyp);
1985 Rtyp := Base_Type (Rtyp);
1986 pragma Assert (Ltyp = Rtyp);
1987 end if;
1988
1dd3915b
EB
1989 -- If the array type is distinct from the type of the arguments, it
1990 -- is the full view of a private type. Apply an unchecked conversion
1991 -- to ensure that analysis of the code below succeeds.
1992
1993 if No (Etype (Lhs))
1994 or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
1995 then
1996 New_Lhs := OK_Convert_To (Ltyp, Lhs);
1997 else
1998 New_Lhs := Lhs;
1999 end if;
2000
2001 if No (Etype (Rhs))
2002 or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
2003 then
2004 New_Rhs := OK_Convert_To (Rtyp, Rhs);
2005 else
2006 New_Rhs := Rhs;
2007 end if;
2008
2009 First_Idx := First_Index (Ltyp);
2010
2011 -- If optimization is enabled and the array boils down to a couple of
2012 -- consecutive elements, generate a simple conjunction of comparisons
2013 -- which should be easier to optimize by the code generator.
2014
2015 if Optimization_Level > 0
2016 and then Ltyp = Rtyp
2017 and then Is_Constrained (Ltyp)
2018 and then Number_Dimensions (Ltyp) = 1
2019 and then Nkind (First_Idx) = N_Range
2020 and then Compile_Time_Known_Value (Low_Bound (First_Idx))
2021 and then Compile_Time_Known_Value (High_Bound (First_Idx))
2022 and then Expr_Value (High_Bound (First_Idx)) =
2023 Expr_Value (Low_Bound (First_Idx)) + 1
2024 then
2025 declare
2026 Ctyp : constant Entity_Id := Component_Type (Ltyp);
2027 L, R : Node_Id;
2028 TestL, TestH : Node_Id;
1dd3915b
EB
2029
2030 begin
1dd3915b
EB
2031 L :=
2032 Make_Indexed_Component (Loc,
2033 Prefix => New_Copy_Tree (New_Lhs),
2e64cf05
EB
2034 Expressions =>
2035 New_List (New_Copy_Tree (Low_Bound (First_Idx))));
1dd3915b
EB
2036
2037 R :=
2038 Make_Indexed_Component (Loc,
2039 Prefix => New_Copy_Tree (New_Rhs),
2e64cf05
EB
2040 Expressions =>
2041 New_List (New_Copy_Tree (Low_Bound (First_Idx))));
1dd3915b
EB
2042
2043 TestL := Expand_Composite_Equality (Nod, Ctyp, L, R, Bodies);
2044
1dd3915b
EB
2045 L :=
2046 Make_Indexed_Component (Loc,
2047 Prefix => New_Lhs,
2e64cf05
EB
2048 Expressions =>
2049 New_List (New_Copy_Tree (High_Bound (First_Idx))));
1dd3915b
EB
2050
2051 R :=
2052 Make_Indexed_Component (Loc,
2053 Prefix => New_Rhs,
2e64cf05
EB
2054 Expressions =>
2055 New_List (New_Copy_Tree (High_Bound (First_Idx))));
1dd3915b
EB
2056
2057 TestH := Expand_Composite_Equality (Nod, Ctyp, L, R, Bodies);
2058
2059 return
2060 Make_And_Then (Loc, Left_Opnd => TestL, Right_Opnd => TestH);
2061 end;
2062 end if;
2063
0da2c8ac
AC
2064 -- Build list of formals for function
2065
70482933
RK
2066 Formals := New_List (
2067 Make_Parameter_Specification (Loc,
2068 Defining_Identifier => A,
e4494292 2069 Parameter_Type => New_Occurrence_Of (Ltyp, Loc)),
70482933
RK
2070
2071 Make_Parameter_Specification (Loc,
2072 Defining_Identifier => B,
e4494292 2073 Parameter_Type => New_Occurrence_Of (Rtyp, Loc)));
70482933 2074
191fcb3a 2075 Func_Name := Make_Temporary (Loc, 'E');
70482933 2076
fbf5a39b 2077 -- Build statement sequence for function
70482933
RK
2078
2079 Func_Body :=
2080 Make_Subprogram_Body (Loc,
2081 Specification =>
2082 Make_Function_Specification (Loc,
2083 Defining_Unit_Name => Func_Name,
2084 Parameter_Specifications => Formals,
e4494292 2085 Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),
fbf5a39b 2086
eedc5882 2087 Declarations => Decls,
fbf5a39b 2088
70482933
RK
2089 Handled_Statement_Sequence =>
2090 Make_Handled_Sequence_Of_Statements (Loc,
2091 Statements => New_List (
fbf5a39b
AC
2092
2093 Make_Implicit_If_Statement (Nod,
cc6f5d75 2094 Condition => Test_Empty_Arrays,
fbf5a39b 2095 Then_Statements => New_List (
d766cee3 2096 Make_Simple_Return_Statement (Loc,
fbf5a39b
AC
2097 Expression =>
2098 New_Occurrence_Of (Standard_True, Loc)))),
2099
2100 Make_Implicit_If_Statement (Nod,
cc6f5d75 2101 Condition => Test_Lengths_Correspond,
fbf5a39b 2102 Then_Statements => New_List (
d766cee3 2103 Make_Simple_Return_Statement (Loc,
cc6f5d75 2104 Expression => New_Occurrence_Of (Standard_False, Loc)))),
fbf5a39b 2105
1dd3915b 2106 Handle_One_Dimension (1, First_Idx),
fbf5a39b 2107
d766cee3 2108 Make_Simple_Return_Statement (Loc,
70482933
RK
2109 Expression => New_Occurrence_Of (Standard_True, Loc)))));
2110
1dd3915b
EB
2111 Set_Has_Completion (Func_Name, True);
2112 Set_Is_Inlined (Func_Name);
70482933 2113
1dd3915b 2114 Append_To (Bodies, Func_Body);
70482933 2115
1dd3915b
EB
2116 return
2117 Make_Function_Call (Loc,
2118 Name => New_Occurrence_Of (Func_Name, Loc),
2119 Parameter_Associations => New_List (New_Lhs, New_Rhs));
70482933
RK
2120 end Expand_Array_Equality;
2121
2122 -----------------------------
2123 -- Expand_Boolean_Operator --
2124 -----------------------------
2125
685094bf
RD
2126 -- Note that we first get the actual subtypes of the operands, since we
2127 -- always want to deal with types that have bounds.
70482933
RK
2128
2129 procedure Expand_Boolean_Operator (N : Node_Id) is
fbf5a39b 2130 Typ : constant Entity_Id := Etype (N);
70482933
RK
2131
2132 begin
685094bf
RD
2133 -- Special case of bit packed array where both operands are known to be
2134 -- properly aligned. In this case we use an efficient run time routine
2135 -- to carry out the operation (see System.Bit_Ops).
a9d8907c
JM
2136
2137 if Is_Bit_Packed_Array (Typ)
2138 and then not Is_Possibly_Unaligned_Object (Left_Opnd (N))
2139 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
2140 then
70482933 2141 Expand_Packed_Boolean_Operator (N);
a9d8907c
JM
2142 return;
2143 end if;
70482933 2144
a9d8907c
JM
2145 -- For the normal non-packed case, the general expansion is to build
2146 -- function for carrying out the comparison (use Make_Boolean_Array_Op)
2147 -- and then inserting it into the tree. The original operator node is
2148 -- then rewritten as a call to this function. We also use this in the
2149 -- packed case if either operand is a possibly unaligned object.
70482933 2150
a9d8907c
JM
2151 declare
2152 Loc : constant Source_Ptr := Sloc (N);
2153 L : constant Node_Id := Relocate_Node (Left_Opnd (N));
076bbec1 2154 R : Node_Id := Relocate_Node (Right_Opnd (N));
a9d8907c
JM
2155 Func_Body : Node_Id;
2156 Func_Name : Entity_Id;
fbf5a39b 2157
a9d8907c
JM
2158 begin
2159 Convert_To_Actual_Subtype (L);
2160 Convert_To_Actual_Subtype (R);
2161 Ensure_Defined (Etype (L), N);
2162 Ensure_Defined (Etype (R), N);
2163 Apply_Length_Check (R, Etype (L));
2164
b4592168 2165 if Nkind (N) = N_Op_Xor then
076bbec1
ES
2166 R := Duplicate_Subexpr (R);
2167 Silly_Boolean_Array_Xor_Test (N, R, Etype (L));
b4592168
GD
2168 end if;
2169
a9d8907c
JM
2170 if Nkind (Parent (N)) = N_Assignment_Statement
2171 and then Safe_In_Place_Array_Op (Name (Parent (N)), L, R)
2172 then
2173 Build_Boolean_Array_Proc_Call (Parent (N), L, R);
fbf5a39b 2174
a9d8907c
JM
2175 elsif Nkind (Parent (N)) = N_Op_Not
2176 and then Nkind (N) = N_Op_And
39f0fa29 2177 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
cc6f5d75 2178 and then Safe_In_Place_Array_Op (Name (Parent (Parent (N))), L, R)
a9d8907c
JM
2179 then
2180 return;
2181 else
a9d8907c
JM
2182 Func_Body := Make_Boolean_Array_Op (Etype (L), N);
2183 Func_Name := Defining_Unit_Name (Specification (Func_Body));
2184 Insert_Action (N, Func_Body);
70482933 2185
a9d8907c 2186 -- Now rewrite the expression with a call
70482933 2187
b50706ef
AC
2188 if Transform_Function_Array then
2189 declare
2190 Temp_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
2191 Call : Node_Id;
2192 Decl : Node_Id;
2193
2194 begin
2195 -- Generate:
2196 -- Temp : ...;
2197
2198 Decl :=
2199 Make_Object_Declaration (Loc,
2200 Defining_Identifier => Temp_Id,
2201 Object_Definition =>
2202 New_Occurrence_Of (Etype (L), Loc));
2203
2204 -- Generate:
2205 -- Proc_Call (L, R, Temp);
2206
2207 Call :=
2208 Make_Procedure_Call_Statement (Loc,
2209 Name => New_Occurrence_Of (Func_Name, Loc),
2210 Parameter_Associations =>
2211 New_List (
2212 L,
2213 Make_Type_Conversion
2214 (Loc, New_Occurrence_Of (Etype (L), Loc), R),
2215 New_Occurrence_Of (Temp_Id, Loc)));
2216
2217 Insert_Actions (Parent (N), New_List (Decl, Call));
2218 Rewrite (N, New_Occurrence_Of (Temp_Id, Loc));
2219 end;
2220 else
2221 Rewrite (N,
2222 Make_Function_Call (Loc,
2223 Name => New_Occurrence_Of (Func_Name, Loc),
2224 Parameter_Associations =>
2225 New_List (
2226 L,
2227 Make_Type_Conversion
2228 (Loc, New_Occurrence_Of (Etype (L), Loc), R))));
2229 end if;
70482933 2230
a9d8907c
JM
2231 Analyze_And_Resolve (N, Typ);
2232 end if;
2233 end;
70482933
RK
2234 end Expand_Boolean_Operator;
2235
456cbfa5
AC
2236 ------------------------------------------------
2237 -- Expand_Compare_Minimize_Eliminate_Overflow --
2238 ------------------------------------------------
2239
2240 procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id) is
2241 Loc : constant Source_Ptr := Sloc (N);
2242
71fb4dc8
AC
2243 Result_Type : constant Entity_Id := Etype (N);
2244 -- Capture result type (could be a derived boolean type)
2245
456cbfa5
AC
2246 Llo, Lhi : Uint;
2247 Rlo, Rhi : Uint;
2248
2249 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
2250 -- Entity for Long_Long_Integer'Base
2251
456cbfa5
AC
2252 procedure Set_True;
2253 procedure Set_False;
2254 -- These procedures rewrite N with an occurrence of Standard_True or
2255 -- Standard_False, and then makes a call to Warn_On_Known_Condition.
2256
2257 ---------------
2258 -- Set_False --
2259 ---------------
2260
2261 procedure Set_False is
2262 begin
2263 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
2264 Warn_On_Known_Condition (N);
2265 end Set_False;
2266
2267 --------------
2268 -- Set_True --
2269 --------------
2270
2271 procedure Set_True is
2272 begin
2273 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
2274 Warn_On_Known_Condition (N);
2275 end Set_True;
2276
2277 -- Start of processing for Expand_Compare_Minimize_Eliminate_Overflow
2278
2279 begin
456cbfa5
AC
2280 -- OK, this is the case we are interested in. First step is to process
2281 -- our operands using the Minimize_Eliminate circuitry which applies
2282 -- this processing to the two operand subtrees.
2283
a7f1b24f 2284 Minimize_Eliminate_Overflows
c7e152b5 2285 (Left_Opnd (N), Llo, Lhi, Top_Level => False);
a7f1b24f 2286 Minimize_Eliminate_Overflows
c7e152b5 2287 (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
456cbfa5 2288
65f7ed64
AC
2289 -- See if the range information decides the result of the comparison.
2290 -- We can only do this if we in fact have full range information (which
2291 -- won't be the case if either operand is bignum at this stage).
456cbfa5 2292
65f7ed64
AC
2293 if Llo /= No_Uint and then Rlo /= No_Uint then
2294 case N_Op_Compare (Nkind (N)) is
d8f43ee6
HK
2295 when N_Op_Eq =>
2296 if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
2297 Set_True;
2298 elsif Llo > Rhi or else Lhi < Rlo then
2299 Set_False;
2300 end if;
456cbfa5 2301
d8f43ee6
HK
2302 when N_Op_Ge =>
2303 if Llo >= Rhi then
2304 Set_True;
2305 elsif Lhi < Rlo then
2306 Set_False;
2307 end if;
456cbfa5 2308
d8f43ee6
HK
2309 when N_Op_Gt =>
2310 if Llo > Rhi then
2311 Set_True;
2312 elsif Lhi <= Rlo then
2313 Set_False;
2314 end if;
456cbfa5 2315
d8f43ee6
HK
2316 when N_Op_Le =>
2317 if Llo > Rhi then
2318 Set_False;
2319 elsif Lhi <= Rlo then
2320 Set_True;
2321 end if;
456cbfa5 2322
d8f43ee6
HK
2323 when N_Op_Lt =>
2324 if Llo >= Rhi then
2325 Set_False;
2326 elsif Lhi < Rlo then
2327 Set_True;
2328 end if;
456cbfa5 2329
d8f43ee6
HK
2330 when N_Op_Ne =>
2331 if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
2332 Set_False;
2333 elsif Llo > Rhi or else Lhi < Rlo then
2334 Set_True;
2335 end if;
65f7ed64 2336 end case;
456cbfa5 2337
65f7ed64 2338 -- All done if we did the rewrite
456cbfa5 2339
65f7ed64
AC
2340 if Nkind (N) not in N_Op_Compare then
2341 return;
2342 end if;
456cbfa5
AC
2343 end if;
2344
2345 -- Otherwise, time to do the comparison
2346
2347 declare
2348 Ltype : constant Entity_Id := Etype (Left_Opnd (N));
2349 Rtype : constant Entity_Id := Etype (Right_Opnd (N));
2350
2351 begin
2352 -- If the two operands have the same signed integer type we are
2353 -- all set, nothing more to do. This is the case where either
2354 -- both operands were unchanged, or we rewrote both of them to
2355 -- be Long_Long_Integer.
2356
2357 -- Note: Entity for the comparison may be wrong, but it's not worth
2358 -- the effort to change it, since the back end does not use it.
2359
2360 if Is_Signed_Integer_Type (Ltype)
2361 and then Base_Type (Ltype) = Base_Type (Rtype)
2362 then
2363 return;
2364
2365 -- Here if bignums are involved (can only happen in ELIMINATED mode)
2366
2367 elsif Is_RTE (Ltype, RE_Bignum) or else Is_RTE (Rtype, RE_Bignum) then
2368 declare
2369 Left : Node_Id := Left_Opnd (N);
2370 Right : Node_Id := Right_Opnd (N);
2371 -- Bignum references for left and right operands
2372
2373 begin
2374 if not Is_RTE (Ltype, RE_Bignum) then
2375 Left := Convert_To_Bignum (Left);
2376 elsif not Is_RTE (Rtype, RE_Bignum) then
2377 Right := Convert_To_Bignum (Right);
2378 end if;
2379
71fb4dc8 2380 -- We rewrite our node with:
456cbfa5 2381
71fb4dc8
AC
2382 -- do
2383 -- Bnn : Result_Type;
2384 -- declare
2385 -- M : Mark_Id := SS_Mark;
2386 -- begin
2387 -- Bnn := Big_xx (Left, Right); (xx = EQ, NT etc)
2388 -- SS_Release (M);
2389 -- end;
2390 -- in
2391 -- Bnn
2392 -- end
456cbfa5
AC
2393
2394 declare
71fb4dc8 2395 Blk : constant Node_Id := Make_Bignum_Block (Loc);
456cbfa5
AC
2396 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
2397 Ent : RE_Id;
2398
2399 begin
2400 case N_Op_Compare (Nkind (N)) is
2401 when N_Op_Eq => Ent := RE_Big_EQ;
2402 when N_Op_Ge => Ent := RE_Big_GE;
2403 when N_Op_Gt => Ent := RE_Big_GT;
2404 when N_Op_Le => Ent := RE_Big_LE;
2405 when N_Op_Lt => Ent := RE_Big_LT;
2406 when N_Op_Ne => Ent := RE_Big_NE;
2407 end case;
2408
71fb4dc8 2409 -- Insert assignment to Bnn into the bignum block
456cbfa5
AC
2410
2411 Insert_Before
2412 (First (Statements (Handled_Statement_Sequence (Blk))),
2413 Make_Assignment_Statement (Loc,
2414 Name => New_Occurrence_Of (Bnn, Loc),
2415 Expression =>
2416 Make_Function_Call (Loc,
2417 Name =>
2418 New_Occurrence_Of (RTE (Ent), Loc),
2419 Parameter_Associations => New_List (Left, Right))));
2420
71fb4dc8
AC
2421 -- Now do the rewrite with expression actions
2422
2423 Rewrite (N,
2424 Make_Expression_With_Actions (Loc,
2425 Actions => New_List (
2426 Make_Object_Declaration (Loc,
2427 Defining_Identifier => Bnn,
2428 Object_Definition =>
2429 New_Occurrence_Of (Result_Type, Loc)),
2430 Blk),
2431 Expression => New_Occurrence_Of (Bnn, Loc)));
2432 Analyze_And_Resolve (N, Result_Type);
456cbfa5
AC
2433 end;
2434 end;
2435
2436 -- No bignums involved, but types are different, so we must have
2437 -- rewritten one of the operands as a Long_Long_Integer but not
2438 -- the other one.
2439
2440 -- If left operand is Long_Long_Integer, convert right operand
2441 -- and we are done (with a comparison of two Long_Long_Integers).
2442
2443 elsif Ltype = LLIB then
2444 Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
2445 Analyze_And_Resolve (Right_Opnd (N), LLIB, Suppress => All_Checks);
2446 return;
2447
2448 -- If right operand is Long_Long_Integer, convert left operand
2449 -- and we are done (with a comparison of two Long_Long_Integers).
2450
2451 -- This is the only remaining possibility
2452
2453 else pragma Assert (Rtype = LLIB);
2454 Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
2455 Analyze_And_Resolve (Left_Opnd (N), LLIB, Suppress => All_Checks);
2456 return;
2457 end if;
2458 end;
2459 end Expand_Compare_Minimize_Eliminate_Overflow;
2460
70482933
RK
2461 -------------------------------
2462 -- Expand_Composite_Equality --
2463 -------------------------------
2464
2465 -- This function is only called for comparing internal fields of composite
2466 -- types when these fields are themselves composites. This is a special
2467 -- case because it is not possible to respect normal Ada visibility rules.
2468
2469 function Expand_Composite_Equality
2470 (Nod : Node_Id;
2471 Typ : Entity_Id;
2472 Lhs : Node_Id;
2473 Rhs : Node_Id;
2e071734 2474 Bodies : List_Id) return Node_Id
70482933
RK
2475 is
2476 Loc : constant Source_Ptr := Sloc (Nod);
2477 Full_Type : Entity_Id;
70482933
RK
2478 Eq_Op : Entity_Id;
2479
7efc3f2d
AC
2480 -- Start of processing for Expand_Composite_Equality
2481
70482933
RK
2482 begin
2483 if Is_Private_Type (Typ) then
2484 Full_Type := Underlying_Type (Typ);
2485 else
2486 Full_Type := Typ;
2487 end if;
2488
ced8450b
ES
2489 -- If the private type has no completion the context may be the
2490 -- expansion of a composite equality for a composite type with some
2491 -- still incomplete components. The expression will not be analyzed
2492 -- until the enclosing type is completed, at which point this will be
2493 -- properly expanded, unless there is a bona fide completion error.
70482933
RK
2494
2495 if No (Full_Type) then
ced8450b 2496 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
70482933
RK
2497 end if;
2498
2499 Full_Type := Base_Type (Full_Type);
2500
da1b76c1
HK
2501 -- When the base type itself is private, use the full view to expand
2502 -- the composite equality.
2503
2504 if Is_Private_Type (Full_Type) then
2505 Full_Type := Underlying_Type (Full_Type);
2506 end if;
2507
16788d44
RD
2508 -- Case of array types
2509
70482933
RK
2510 if Is_Array_Type (Full_Type) then
2511
2512 -- If the operand is an elementary type other than a floating-point
2513 -- type, then we can simply use the built-in block bitwise equality,
2514 -- since the predefined equality operators always apply and bitwise
2515 -- equality is fine for all these cases.
2516
2517 if Is_Elementary_Type (Component_Type (Full_Type))
2518 and then not Is_Floating_Point_Type (Component_Type (Full_Type))
2519 then
39ade2f9 2520 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
70482933 2521
685094bf
RD
2522 -- For composite component types, and floating-point types, use the
2523 -- expansion. This deals with tagged component types (where we use
0c386027 2524 -- the applicable equality routine) and floating-point (where we
685094bf
RD
2525 -- need to worry about negative zeroes), and also the case of any
2526 -- composite type recursively containing such fields.
70482933
RK
2527
2528 else
0c386027
EB
2529 declare
2530 Comp_Typ : Entity_Id;
f537fc00 2531 Hi : Node_Id;
bcad5029
EB
2532 Indx : Node_Id;
2533 Ityp : Entity_Id;
2534 Lo : Node_Id;
0c386027
EB
2535
2536 begin
2537 -- Do the comparison in the type (or its full view) and not in
2538 -- its unconstrained base type, because the latter operation is
2539 -- more complex and would also require an unchecked conversion.
2540
2541 if Is_Private_Type (Typ) then
2542 Comp_Typ := Underlying_Type (Typ);
2543 else
2544 Comp_Typ := Typ;
2545 end if;
2546
2547 -- Except for the case where the bounds of the type depend on a
2548 -- discriminant, or else we would run into scoping issues.
2549
bcad5029
EB
2550 Indx := First_Index (Comp_Typ);
2551 while Present (Indx) loop
2552 Ityp := Etype (Indx);
2553
2554 Lo := Type_Low_Bound (Ityp);
2555 Hi := Type_High_Bound (Ityp);
2556
2557 if (Nkind (Lo) = N_Identifier
2558 and then Ekind (Entity (Lo)) = E_Discriminant)
2559 or else
2560 (Nkind (Hi) = N_Identifier
2561 and then Ekind (Entity (Hi)) = E_Discriminant)
2562 then
2563 Comp_Typ := Full_Type;
2564 exit;
2565 end if;
2566
2567 Next_Index (Indx);
2568 end loop;
0c386027
EB
2569
2570 return Expand_Array_Equality (Nod, Lhs, Rhs, Bodies, Comp_Typ);
2571 end;
70482933
RK
2572 end if;
2573
16788d44
RD
2574 -- Case of tagged record types
2575
70482933 2576 elsif Is_Tagged_Type (Full_Type) then
59f7c716
JM
2577 Eq_Op := Find_Primitive_Eq (Typ);
2578 pragma Assert (Present (Eq_Op));
70482933
RK
2579
2580 return
2581 Make_Function_Call (Loc,
e4494292 2582 Name => New_Occurrence_Of (Eq_Op, Loc),
70482933
RK
2583 Parameter_Associations =>
2584 New_List
2585 (Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Lhs),
2586 Unchecked_Convert_To (Etype (First_Formal (Eq_Op)), Rhs)));
2587
16788d44
RD
2588 -- Case of untagged record types
2589
70482933 2590 elsif Is_Record_Type (Full_Type) then
fbf5a39b 2591 Eq_Op := TSS (Full_Type, TSS_Composite_Equality);
70482933
RK
2592
2593 if Present (Eq_Op) then
2594 if Etype (First_Formal (Eq_Op)) /= Full_Type then
2595
685094bf
RD
2596 -- Inherited equality from parent type. Convert the actuals to
2597 -- match signature of operation.
70482933
RK
2598
2599 declare
fbf5a39b 2600 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
70482933
RK
2601
2602 begin
2603 return
2604 Make_Function_Call (Loc,
e4494292 2605 Name => New_Occurrence_Of (Eq_Op, Loc),
39ade2f9
AC
2606 Parameter_Associations => New_List (
2607 OK_Convert_To (T, Lhs),
2608 OK_Convert_To (T, Rhs)));
70482933
RK
2609 end;
2610
2611 else
5d09245e
AC
2612 -- Comparison between Unchecked_Union components
2613
2614 if Is_Unchecked_Union (Full_Type) then
2615 declare
2616 Lhs_Type : Node_Id := Full_Type;
2617 Rhs_Type : Node_Id := Full_Type;
2618 Lhs_Discr_Val : Node_Id;
2619 Rhs_Discr_Val : Node_Id;
2620
2621 begin
2622 -- Lhs subtype
2623
2624 if Nkind (Lhs) = N_Selected_Component then
2625 Lhs_Type := Etype (Entity (Selector_Name (Lhs)));
2626 end if;
2627
2628 -- Rhs subtype
2629
2630 if Nkind (Rhs) = N_Selected_Component then
2631 Rhs_Type := Etype (Entity (Selector_Name (Rhs)));
2632 end if;
2633
2634 -- Lhs of the composite equality
2635
2636 if Is_Constrained (Lhs_Type) then
2637
685094bf 2638 -- Since the enclosing record type can never be an
5d09245e
AC
2639 -- Unchecked_Union (this code is executed for records
2640 -- that do not have variants), we may reference its
2641 -- discriminant(s).
2642
2643 if Nkind (Lhs) = N_Selected_Component
533369aa
AC
2644 and then Has_Per_Object_Constraint
2645 (Entity (Selector_Name (Lhs)))
5d09245e
AC
2646 then
2647 Lhs_Discr_Val :=
2648 Make_Selected_Component (Loc,
39ade2f9 2649 Prefix => Prefix (Lhs),
5d09245e 2650 Selector_Name =>
39ade2f9
AC
2651 New_Copy
2652 (Get_Discriminant_Value
2653 (First_Discriminant (Lhs_Type),
2654 Lhs_Type,
2655 Stored_Constraint (Lhs_Type))));
5d09245e
AC
2656
2657 else
39ade2f9
AC
2658 Lhs_Discr_Val :=
2659 New_Copy
2660 (Get_Discriminant_Value
2661 (First_Discriminant (Lhs_Type),
2662 Lhs_Type,
2663 Stored_Constraint (Lhs_Type)));
5d09245e
AC
2664
2665 end if;
2666 else
2667 -- It is not possible to infer the discriminant since
2668 -- the subtype is not constrained.
2669
8aceda64 2670 return
5d09245e 2671 Make_Raise_Program_Error (Loc,
8aceda64 2672 Reason => PE_Unchecked_Union_Restriction);
5d09245e
AC
2673 end if;
2674
2675 -- Rhs of the composite equality
2676
2677 if Is_Constrained (Rhs_Type) then
2678 if Nkind (Rhs) = N_Selected_Component
39ade2f9
AC
2679 and then Has_Per_Object_Constraint
2680 (Entity (Selector_Name (Rhs)))
5d09245e
AC
2681 then
2682 Rhs_Discr_Val :=
2683 Make_Selected_Component (Loc,
39ade2f9 2684 Prefix => Prefix (Rhs),
5d09245e 2685 Selector_Name =>
39ade2f9
AC
2686 New_Copy
2687 (Get_Discriminant_Value
2688 (First_Discriminant (Rhs_Type),
2689 Rhs_Type,
2690 Stored_Constraint (Rhs_Type))));
5d09245e
AC
2691
2692 else
39ade2f9
AC
2693 Rhs_Discr_Val :=
2694 New_Copy
2695 (Get_Discriminant_Value
2696 (First_Discriminant (Rhs_Type),
2697 Rhs_Type,
2698 Stored_Constraint (Rhs_Type)));
5d09245e
AC
2699
2700 end if;
2701 else
8aceda64 2702 return
5d09245e 2703 Make_Raise_Program_Error (Loc,
8aceda64 2704 Reason => PE_Unchecked_Union_Restriction);
5d09245e
AC
2705 end if;
2706
2707 -- Call the TSS equality function with the inferred
2708 -- discriminant values.
2709
2710 return
2711 Make_Function_Call (Loc,
e4494292 2712 Name => New_Occurrence_Of (Eq_Op, Loc),
5d09245e
AC
2713 Parameter_Associations => New_List (
2714 Lhs,
2715 Rhs,
2716 Lhs_Discr_Val,
2717 Rhs_Discr_Val));
2718 end;
d151d6a3 2719
316e3a13
RD
2720 -- All cases other than comparing Unchecked_Union types
2721
d151d6a3 2722 else
7f1a5156
EB
2723 declare
2724 T : constant Entity_Id := Etype (First_Formal (Eq_Op));
7f1a5156
EB
2725 begin
2726 return
2727 Make_Function_Call (Loc,
316e3a13
RD
2728 Name =>
2729 New_Occurrence_Of (Eq_Op, Loc),
7f1a5156
EB
2730 Parameter_Associations => New_List (
2731 OK_Convert_To (T, Lhs),
2732 OK_Convert_To (T, Rhs)));
2733 end;
5d09245e 2734 end if;
d151d6a3 2735 end if;
5d09245e 2736
3058f181
BD
2737 -- Equality composes in Ada 2012 for untagged record types. It also
2738 -- composes for bounded strings, because they are part of the
2739 -- predefined environment. We could make it compose for bounded
2740 -- strings by making them tagged, or by making sure all subcomponents
2741 -- are set to the same value, even when not used. Instead, we have
2742 -- this special case in the compiler, because it's more efficient.
2743
2744 elsif Ada_Version >= Ada_2012 or else Is_Bounded_String (Typ) then
5d09245e 2745
08daa782 2746 -- If no TSS has been created for the type, check whether there is
7efc3f2d 2747 -- a primitive equality declared for it.
d151d6a3
AC
2748
2749 declare
bdbb2a40 2750 Op : constant Node_Id := Build_Eq_Call (Typ, Loc, Lhs, Rhs);
d151d6a3
AC
2751
2752 begin
a1fc903a
AC
2753 -- Use user-defined primitive if it exists, otherwise use
2754 -- predefined equality.
2755
3058f181
BD
2756 if Present (Op) then
2757 return Op;
7efc3f2d 2758 else
7efc3f2d
AC
2759 return Make_Op_Eq (Loc, Lhs, Rhs);
2760 end if;
d151d6a3
AC
2761 end;
2762
70482933
RK
2763 else
2764 return Expand_Record_Equality (Nod, Full_Type, Lhs, Rhs, Bodies);
2765 end if;
2766
16788d44 2767 -- Non-composite types (always use predefined equality)
70482933 2768
16788d44 2769 else
70482933
RK
2770 return Make_Op_Eq (Loc, Left_Opnd => Lhs, Right_Opnd => Rhs);
2771 end if;
2772 end Expand_Composite_Equality;
2773
fdac1f80
AC
2774 ------------------------
2775 -- Expand_Concatenate --
2776 ------------------------
70482933 2777
fdac1f80
AC
2778 procedure Expand_Concatenate (Cnode : Node_Id; Opnds : List_Id) is
2779 Loc : constant Source_Ptr := Sloc (Cnode);
70482933 2780
fdac1f80
AC
2781 Atyp : constant Entity_Id := Base_Type (Etype (Cnode));
2782 -- Result type of concatenation
70482933 2783
fdac1f80
AC
2784 Ctyp : constant Entity_Id := Base_Type (Component_Type (Etype (Cnode)));
2785 -- Component type. Elements of this component type can appear as one
2786 -- of the operands of concatenation as well as arrays.
70482933 2787
ecc4ddde
AC
2788 Istyp : constant Entity_Id := Etype (First_Index (Atyp));
2789 -- Index subtype
2790
2791 Ityp : constant Entity_Id := Base_Type (Istyp);
2792 -- Index type. This is the base type of the index subtype, and is used
2793 -- for all computed bounds (which may be out of range of Istyp in the
2794 -- case of null ranges).
70482933 2795
46ff89f3 2796 Artyp : Entity_Id;
fdac1f80
AC
2797 -- This is the type we use to do arithmetic to compute the bounds and
2798 -- lengths of operands. The choice of this type is a little subtle and
2799 -- is discussed in a separate section at the start of the body code.
70482933 2800
fdac1f80
AC
2801 Concatenation_Error : exception;
2802 -- Raised if concatenation is sure to raise a CE
70482933 2803
0ac73189
AC
2804 Result_May_Be_Null : Boolean := True;
2805 -- Reset to False if at least one operand is encountered which is known
2806 -- at compile time to be non-null. Used for handling the special case
2807 -- of setting the high bound to the last operand high bound for a null
2808 -- result, thus ensuring a proper high bound in the super-flat case.
2809
df46b832 2810 N : constant Nat := List_Length (Opnds);
fdac1f80 2811 -- Number of concatenation operands including possibly null operands
df46b832
AC
2812
2813 NN : Nat := 0;
a29262fd
AC
2814 -- Number of operands excluding any known to be null, except that the
2815 -- last operand is always retained, in case it provides the bounds for
2816 -- a null result.
2817
a6d25cad 2818 Opnd : Node_Id := Empty;
a29262fd
AC
2819 -- Current operand being processed in the loop through operands. After
2820 -- this loop is complete, always contains the last operand (which is not
2821 -- the same as Operands (NN), since null operands are skipped).
df46b832
AC
2822
2823 -- Arrays describing the operands, only the first NN entries of each
2824 -- array are set (NN < N when we exclude known null operands).
2825
2826 Is_Fixed_Length : array (1 .. N) of Boolean;
2827 -- True if length of corresponding operand known at compile time
2828
2829 Operands : array (1 .. N) of Node_Id;
a29262fd
AC
2830 -- Set to the corresponding entry in the Opnds list (but note that null
2831 -- operands are excluded, so not all entries in the list are stored).
df46b832
AC
2832
2833 Fixed_Length : array (1 .. N) of Uint;
fdac1f80
AC
2834 -- Set to length of operand. Entries in this array are set only if the
2835 -- corresponding entry in Is_Fixed_Length is True.
df46b832 2836
0ac73189
AC
2837 Opnd_Low_Bound : array (1 .. N) of Node_Id;
2838 -- Set to lower bound of operand. Either an integer literal in the case
2839 -- where the bound is known at compile time, else actual lower bound.
2840 -- The operand low bound is of type Ityp.
2841
df46b832
AC
2842 Var_Length : array (1 .. N) of Entity_Id;
2843 -- Set to an entity of type Natural that contains the length of an
2844 -- operand whose length is not known at compile time. Entries in this
2845 -- array are set only if the corresponding entry in Is_Fixed_Length
46ff89f3 2846 -- is False. The entity is of type Artyp.
df46b832
AC
2847
2848 Aggr_Length : array (0 .. N) of Node_Id;
fdac1f80
AC
2849 -- The J'th entry in an expression node that represents the total length
2850 -- of operands 1 through J. It is either an integer literal node, or a
2851 -- reference to a constant entity with the right value, so it is fine
31fde973 2852 -- to just do a Copy_Node to get an appropriate copy. The extra zeroth
46ff89f3 2853 -- entry always is set to zero. The length is of type Artyp.
df46b832 2854
a6b13d32 2855 Low_Bound : Node_Id := Empty;
0ac73189
AC
2856 -- A tree node representing the low bound of the result (of type Ityp).
2857 -- This is either an integer literal node, or an identifier reference to
2858 -- a constant entity initialized to the appropriate value.
2859
a6d25cad 2860 Last_Opnd_Low_Bound : Node_Id := Empty;
88a27b18
AC
2861 -- A tree node representing the low bound of the last operand. This
2862 -- need only be set if the result could be null. It is used for the
2863 -- special case of setting the right low bound for a null result.
2864 -- This is of type Ityp.
2865
a6d25cad 2866 Last_Opnd_High_Bound : Node_Id := Empty;
a29262fd
AC
2867 -- A tree node representing the high bound of the last operand. This
2868 -- need only be set if the result could be null. It is used for the
2869 -- special case of setting the right high bound for a null result.
2870 -- This is of type Ityp.
2871
dcd5fd67 2872 High_Bound : Node_Id := Empty;
0ac73189 2873 -- A tree node representing the high bound of the result (of type Ityp)
df46b832 2874
a6b13d32 2875 Result : Node_Id := Empty;
0ac73189 2876 -- Result of the concatenation (of type Ityp)
df46b832 2877
d0f8d157 2878 Actions : constant List_Id := New_List;
4c9fe6c7 2879 -- Collect actions to be inserted
d0f8d157 2880
fa969310 2881 Known_Non_Null_Operand_Seen : Boolean;
308e6f3a 2882 -- Set True during generation of the assignments of operands into
fa969310
AC
2883 -- result once an operand known to be non-null has been seen.
2884
2df23f66
AC
2885 function Library_Level_Target return Boolean;
2886 -- Return True if the concatenation is within the expression of the
2887 -- declaration of a library-level object.
2888
fa969310
AC
2889 function Make_Artyp_Literal (Val : Nat) return Node_Id;
2890 -- This function makes an N_Integer_Literal node that is returned in
2891 -- analyzed form with the type set to Artyp. Importantly this literal
2892 -- is not flagged as static, so that if we do computations with it that
2893 -- result in statically detected out of range conditions, we will not
2894 -- generate error messages but instead warning messages.
2895
46ff89f3 2896 function To_Artyp (X : Node_Id) return Node_Id;
fdac1f80 2897 -- Given a node of type Ityp, returns the corresponding value of type
76c597a1
AC
2898 -- Artyp. For non-enumeration types, this is a plain integer conversion.
2899 -- For enum types, the Pos of the value is returned.
fdac1f80
AC
2900
2901 function To_Ityp (X : Node_Id) return Node_Id;
0ac73189 2902 -- The inverse function (uses Val in the case of enumeration types)
fdac1f80 2903
2df23f66
AC
2904 --------------------------
2905 -- Library_Level_Target --
2906 --------------------------
2907
2908 function Library_Level_Target return Boolean is
2909 P : Node_Id := Parent (Cnode);
2910
2911 begin
2912 while Present (P) loop
2913 if Nkind (P) = N_Object_Declaration then
2914 return Is_Library_Level_Entity (Defining_Identifier (P));
2915
2916 -- Prevent the search from going too far
2917
2918 elsif Is_Body_Or_Package_Declaration (P) then
2919 return False;
2920 end if;
2921
2922 P := Parent (P);
2923 end loop;
2924
2925 return False;
2926 end Library_Level_Target;
2927
fa969310
AC
2928 ------------------------
2929 -- Make_Artyp_Literal --
2930 ------------------------
2931
2932 function Make_Artyp_Literal (Val : Nat) return Node_Id is
2933 Result : constant Node_Id := Make_Integer_Literal (Loc, Val);
2934 begin
2935 Set_Etype (Result, Artyp);
2936 Set_Analyzed (Result, True);
2937 Set_Is_Static_Expression (Result, False);
2938 return Result;
2939 end Make_Artyp_Literal;
76c597a1 2940
fdac1f80 2941 --------------
46ff89f3 2942 -- To_Artyp --
fdac1f80
AC
2943 --------------
2944
46ff89f3 2945 function To_Artyp (X : Node_Id) return Node_Id is
fdac1f80 2946 begin
46ff89f3 2947 if Ityp = Base_Type (Artyp) then
fdac1f80
AC
2948 return X;
2949
2950 elsif Is_Enumeration_Type (Ityp) then
2951 return
2952 Make_Attribute_Reference (Loc,
2953 Prefix => New_Occurrence_Of (Ityp, Loc),
2954 Attribute_Name => Name_Pos,
2955 Expressions => New_List (X));
2956
2957 else
46ff89f3 2958 return Convert_To (Artyp, X);
fdac1f80 2959 end if;
46ff89f3 2960 end To_Artyp;
fdac1f80
AC
2961
2962 -------------
2963 -- To_Ityp --
2964 -------------
2965
2966 function To_Ityp (X : Node_Id) return Node_Id is
2967 begin
2fc05e3d 2968 if Is_Enumeration_Type (Ityp) then
fdac1f80
AC
2969 return
2970 Make_Attribute_Reference (Loc,
2971 Prefix => New_Occurrence_Of (Ityp, Loc),
2972 Attribute_Name => Name_Val,
2973 Expressions => New_List (X));
2974
2975 -- Case where we will do a type conversion
2976
2977 else
76c597a1
AC
2978 if Ityp = Base_Type (Artyp) then
2979 return X;
fdac1f80 2980 else
76c597a1 2981 return Convert_To (Ityp, X);
fdac1f80
AC
2982 end if;
2983 end if;
2984 end To_Ityp;
2985
2986 -- Local Declarations
2987
263bb393
AC
2988 Opnd_Typ : Entity_Id;
2989 Subtyp_Ind : Entity_Id;
2990 Ent : Entity_Id;
2991 Len : Uint;
2992 J : Nat;
2993 Clen : Node_Id;
2994 Set : Boolean;
70482933 2995
f46faa08
AC
2996 -- Start of processing for Expand_Concatenate
2997
70482933 2998 begin
fdac1f80
AC
2999 -- Choose an appropriate computational type
3000
3001 -- We will be doing calculations of lengths and bounds in this routine
3002 -- and computing one from the other in some cases, e.g. getting the high
3003 -- bound by adding the length-1 to the low bound.
3004
3005 -- We can't just use the index type, or even its base type for this
3006 -- purpose for two reasons. First it might be an enumeration type which
308e6f3a
RW
3007 -- is not suitable for computations of any kind, and second it may
3008 -- simply not have enough range. For example if the index type is
3009 -- -128..+127 then lengths can be up to 256, which is out of range of
3010 -- the type.
fdac1f80
AC
3011
3012 -- For enumeration types, we can simply use Standard_Integer, this is
3013 -- sufficient since the actual number of enumeration literals cannot
3014 -- possibly exceed the range of integer (remember we will be doing the
0ac73189 3015 -- arithmetic with POS values, not representation values).
fdac1f80
AC
3016
3017 if Is_Enumeration_Type (Ityp) then
46ff89f3 3018 Artyp := Standard_Integer;
fdac1f80 3019
2fc05e3d
AC
3020 -- For modular types, we use a 32-bit modular type for types whose size
3021 -- is in the range 1-31 bits. For 32-bit unsigned types, we use the
cbe3b8d4 3022 -- identity type, and for larger unsigned types we use a 64-bit type.
fdac1f80 3023
2fc05e3d 3024 elsif Is_Modular_Integer_Type (Ityp) then
cbe3b8d4 3025 if RM_Size (Ityp) < Standard_Integer_Size then
46ff89f3 3026 Artyp := Standard_Unsigned;
cbe3b8d4 3027 elsif RM_Size (Ityp) = Standard_Integer_Size then
46ff89f3 3028 Artyp := Ityp;
fdac1f80 3029 else
cbe3b8d4 3030 Artyp := Standard_Long_Long_Unsigned;
fdac1f80
AC
3031 end if;
3032
2fc05e3d 3033 -- Similar treatment for signed types
fdac1f80
AC
3034
3035 else
cbe3b8d4 3036 if RM_Size (Ityp) < Standard_Integer_Size then
46ff89f3 3037 Artyp := Standard_Integer;
cbe3b8d4 3038 elsif RM_Size (Ityp) = Standard_Integer_Size then
46ff89f3 3039 Artyp := Ityp;
fdac1f80 3040 else
46ff89f3 3041 Artyp := Standard_Long_Long_Integer;
fdac1f80
AC
3042 end if;
3043 end if;
3044
fa969310
AC
3045 -- Supply dummy entry at start of length array
3046
3047 Aggr_Length (0) := Make_Artyp_Literal (0);
3048
fdac1f80 3049 -- Go through operands setting up the above arrays
70482933 3050
df46b832
AC
3051 J := 1;
3052 while J <= N loop
3053 Opnd := Remove_Head (Opnds);
0ac73189 3054 Opnd_Typ := Etype (Opnd);
fdac1f80
AC
3055
3056 -- The parent got messed up when we put the operands in a list,
d347f572
AC
3057 -- so now put back the proper parent for the saved operand, that
3058 -- is to say the concatenation node, to make sure that each operand
3059 -- is seen as a subexpression, e.g. if actions must be inserted.
fdac1f80 3060
d347f572 3061 Set_Parent (Opnd, Cnode);
fdac1f80
AC
3062
3063 -- Set will be True when we have setup one entry in the array
3064
df46b832
AC
3065 Set := False;
3066
fdac1f80 3067 -- Singleton element (or character literal) case
df46b832 3068
0ac73189 3069 if Base_Type (Opnd_Typ) = Ctyp then
df46b832
AC
3070 NN := NN + 1;
3071 Operands (NN) := Opnd;
3072 Is_Fixed_Length (NN) := True;
3073 Fixed_Length (NN) := Uint_1;
0ac73189 3074 Result_May_Be_Null := False;
fdac1f80 3075
a29262fd
AC
3076 -- Set low bound of operand (no need to set Last_Opnd_High_Bound
3077 -- since we know that the result cannot be null).
fdac1f80 3078
0ac73189
AC
3079 Opnd_Low_Bound (NN) :=
3080 Make_Attribute_Reference (Loc,
e4494292 3081 Prefix => New_Occurrence_Of (Istyp, Loc),
0ac73189
AC
3082 Attribute_Name => Name_First);
3083
df46b832
AC
3084 Set := True;
3085
fdac1f80 3086 -- String literal case (can only occur for strings of course)
df46b832
AC
3087
3088 elsif Nkind (Opnd) = N_String_Literal then
0ac73189 3089 Len := String_Literal_Length (Opnd_Typ);
df46b832 3090
a29262fd
AC
3091 if Len /= 0 then
3092 Result_May_Be_Null := False;
3093 end if;
3094
88a27b18 3095 -- Capture last operand low and high bound if result could be null
a29262fd
AC
3096
3097 if J = N and then Result_May_Be_Null then
88a27b18
AC
3098 Last_Opnd_Low_Bound :=
3099 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
3100
a29262fd 3101 Last_Opnd_High_Bound :=
88a27b18 3102 Make_Op_Subtract (Loc,
a29262fd
AC
3103 Left_Opnd =>
3104 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ)),
59262ebb 3105 Right_Opnd => Make_Integer_Literal (Loc, 1));
a29262fd
AC
3106 end if;
3107
3108 -- Skip null string literal
fdac1f80 3109
0ac73189 3110 if J < N and then Len = 0 then
df46b832
AC
3111 goto Continue;
3112 end if;
3113
3114 NN := NN + 1;
3115 Operands (NN) := Opnd;
3116 Is_Fixed_Length (NN) := True;
0ac73189
AC
3117
3118 -- Set length and bounds
3119
df46b832 3120 Fixed_Length (NN) := Len;
0ac73189
AC
3121
3122 Opnd_Low_Bound (NN) :=
3123 New_Copy_Tree (String_Literal_Low_Bound (Opnd_Typ));
3124
df46b832
AC
3125 Set := True;
3126
3127 -- All other cases
3128
3129 else
3130 -- Check constrained case with known bounds
3131
0ac73189 3132 if Is_Constrained (Opnd_Typ) then
df46b832 3133 declare
df46b832
AC
3134 Index : constant Node_Id := First_Index (Opnd_Typ);
3135 Indx_Typ : constant Entity_Id := Etype (Index);
3136 Lo : constant Node_Id := Type_Low_Bound (Indx_Typ);
3137 Hi : constant Node_Id := Type_High_Bound (Indx_Typ);
3138
3139 begin
fdac1f80
AC
3140 -- Fixed length constrained array type with known at compile
3141 -- time bounds is last case of fixed length operand.
df46b832
AC
3142
3143 if Compile_Time_Known_Value (Lo)
3144 and then
3145 Compile_Time_Known_Value (Hi)
3146 then
3147 declare
3148 Loval : constant Uint := Expr_Value (Lo);
3149 Hival : constant Uint := Expr_Value (Hi);
3150 Len : constant Uint :=
3151 UI_Max (Hival - Loval + 1, Uint_0);
3152
3153 begin
0ac73189
AC
3154 if Len > 0 then
3155 Result_May_Be_Null := False;
df46b832 3156 end if;
0ac73189 3157
88a27b18 3158 -- Capture last operand bounds if result could be null
a29262fd
AC
3159
3160 if J = N and then Result_May_Be_Null then
88a27b18
AC
3161 Last_Opnd_Low_Bound :=
3162 Convert_To (Ityp,
3163 Make_Integer_Literal (Loc, Expr_Value (Lo)));
3164
a29262fd
AC
3165 Last_Opnd_High_Bound :=
3166 Convert_To (Ityp,
39ade2f9 3167 Make_Integer_Literal (Loc, Expr_Value (Hi)));
a29262fd
AC
3168 end if;
3169
3170 -- Exclude null length case unless last operand
0ac73189 3171
a29262fd 3172 if J < N and then Len = 0 then
0ac73189
AC
3173 goto Continue;
3174 end if;
3175
3176 NN := NN + 1;
3177 Operands (NN) := Opnd;
3178 Is_Fixed_Length (NN) := True;
3179 Fixed_Length (NN) := Len;
3180
39ade2f9
AC
3181 Opnd_Low_Bound (NN) :=
3182 To_Ityp
3183 (Make_Integer_Literal (Loc, Expr_Value (Lo)));
0ac73189 3184 Set := True;
df46b832
AC
3185 end;
3186 end if;
3187 end;
3188 end if;
3189
0ac73189
AC
3190 -- All cases where the length is not known at compile time, or the
3191 -- special case of an operand which is known to be null but has a
3192 -- lower bound other than 1 or is other than a string type.
df46b832
AC
3193
3194 if not Set then
3195 NN := NN + 1;
0ac73189
AC
3196
3197 -- Capture operand bounds
3198
3199 Opnd_Low_Bound (NN) :=
3200 Make_Attribute_Reference (Loc,
3201 Prefix =>
3202 Duplicate_Subexpr (Opnd, Name_Req => True),
3203 Attribute_Name => Name_First);
3204
88a27b18
AC
3205 -- Capture last operand bounds if result could be null
3206
a29262fd 3207 if J = N and Result_May_Be_Null then
88a27b18
AC
3208 Last_Opnd_Low_Bound :=
3209 Convert_To (Ityp,
3210 Make_Attribute_Reference (Loc,
3211 Prefix =>
3212 Duplicate_Subexpr (Opnd, Name_Req => True),
3213 Attribute_Name => Name_First));
3214
a29262fd
AC
3215 Last_Opnd_High_Bound :=
3216 Convert_To (Ityp,
3217 Make_Attribute_Reference (Loc,
3218 Prefix =>
3219 Duplicate_Subexpr (Opnd, Name_Req => True),
3220 Attribute_Name => Name_Last));
3221 end if;
0ac73189
AC
3222
3223 -- Capture length of operand in entity
3224
df46b832
AC
3225 Operands (NN) := Opnd;
3226 Is_Fixed_Length (NN) := False;
3227
191fcb3a 3228 Var_Length (NN) := Make_Temporary (Loc, 'L');
df46b832 3229
d0f8d157 3230 Append_To (Actions,
df46b832
AC
3231 Make_Object_Declaration (Loc,
3232 Defining_Identifier => Var_Length (NN),
3233 Constant_Present => True,
39ade2f9 3234 Object_Definition => New_Occurrence_Of (Artyp, Loc),
df46b832
AC
3235 Expression =>
3236 Make_Attribute_Reference (Loc,
3237 Prefix =>
3238 Duplicate_Subexpr (Opnd, Name_Req => True),
d0f8d157 3239 Attribute_Name => Name_Length)));
df46b832
AC
3240 end if;
3241 end if;
3242
3243 -- Set next entry in aggregate length array
3244
3245 -- For first entry, make either integer literal for fixed length
0ac73189 3246 -- or a reference to the saved length for variable length.
df46b832
AC
3247
3248 if NN = 1 then
3249 if Is_Fixed_Length (1) then
39ade2f9 3250 Aggr_Length (1) := Make_Integer_Literal (Loc, Fixed_Length (1));
df46b832 3251 else
e4494292 3252 Aggr_Length (1) := New_Occurrence_Of (Var_Length (1), Loc);
df46b832
AC
3253 end if;
3254
3255 -- If entry is fixed length and only fixed lengths so far, make
3256 -- appropriate new integer literal adding new length.
3257
3258 elsif Is_Fixed_Length (NN)
3259 and then Nkind (Aggr_Length (NN - 1)) = N_Integer_Literal
3260 then
3261 Aggr_Length (NN) :=
3262 Make_Integer_Literal (Loc,
3263 Intval => Fixed_Length (NN) + Intval (Aggr_Length (NN - 1)));
3264
d0f8d157
AC
3265 -- All other cases, construct an addition node for the length and
3266 -- create an entity initialized to this length.
df46b832
AC
3267
3268 else
191fcb3a 3269 Ent := Make_Temporary (Loc, 'L');
df46b832
AC
3270
3271 if Is_Fixed_Length (NN) then
3272 Clen := Make_Integer_Literal (Loc, Fixed_Length (NN));
3273 else
e4494292 3274 Clen := New_Occurrence_Of (Var_Length (NN), Loc);
df46b832
AC
3275 end if;
3276
d0f8d157 3277 Append_To (Actions,
df46b832
AC
3278 Make_Object_Declaration (Loc,
3279 Defining_Identifier => Ent,
3280 Constant_Present => True,
39ade2f9 3281 Object_Definition => New_Occurrence_Of (Artyp, Loc),
df46b832
AC
3282 Expression =>
3283 Make_Op_Add (Loc,
683af98c 3284 Left_Opnd => New_Copy_Tree (Aggr_Length (NN - 1)),
d0f8d157 3285 Right_Opnd => Clen)));
df46b832 3286
76c597a1 3287 Aggr_Length (NN) := Make_Identifier (Loc, Chars => Chars (Ent));
df46b832
AC
3288 end if;
3289
3290 <<Continue>>
3291 J := J + 1;
3292 end loop;
3293
a29262fd 3294 -- If we have only skipped null operands, return the last operand
df46b832
AC
3295
3296 if NN = 0 then
a29262fd 3297 Result := Opnd;
df46b832
AC
3298 goto Done;
3299 end if;
3300
3301 -- If we have only one non-null operand, return it and we are done.
3302 -- There is one case in which this cannot be done, and that is when
fdac1f80
AC
3303 -- the sole operand is of the element type, in which case it must be
3304 -- converted to an array, and the easiest way of doing that is to go
df46b832
AC
3305 -- through the normal general circuit.
3306
533369aa 3307 if NN = 1 and then Base_Type (Etype (Operands (1))) /= Ctyp then
df46b832
AC
3308 Result := Operands (1);
3309 goto Done;
3310 end if;
3311
3312 -- Cases where we have a real concatenation
3313
fdac1f80
AC
3314 -- Next step is to find the low bound for the result array that we
3315 -- will allocate. The rules for this are in (RM 4.5.6(5-7)).
3316
3317 -- If the ultimate ancestor of the index subtype is a constrained array
3318 -- definition, then the lower bound is that of the index subtype as
3319 -- specified by (RM 4.5.3(6)).
3320
3321 -- The right test here is to go to the root type, and then the ultimate
3322 -- ancestor is the first subtype of this root type.
3323
3324 if Is_Constrained (First_Subtype (Root_Type (Atyp))) then
0ac73189 3325 Low_Bound :=
fdac1f80
AC
3326 Make_Attribute_Reference (Loc,
3327 Prefix =>
3328 New_Occurrence_Of (First_Subtype (Root_Type (Atyp)), Loc),
0ac73189 3329 Attribute_Name => Name_First);
df46b832
AC
3330
3331 -- If the first operand in the list has known length we know that
3332 -- the lower bound of the result is the lower bound of this operand.
3333
fdac1f80 3334 elsif Is_Fixed_Length (1) then
0ac73189 3335 Low_Bound := Opnd_Low_Bound (1);
df46b832
AC
3336
3337 -- OK, we don't know the lower bound, we have to build a horrible
9b16cb57 3338 -- if expression node of the form
df46b832
AC
3339
3340 -- if Cond1'Length /= 0 then
0ac73189 3341 -- Opnd1 low bound
df46b832
AC
3342 -- else
3343 -- if Opnd2'Length /= 0 then
0ac73189 3344 -- Opnd2 low bound
df46b832
AC
3345 -- else
3346 -- ...
3347
3348 -- The nesting ends either when we hit an operand whose length is known
3349 -- at compile time, or on reaching the last operand, whose low bound we
3350 -- take unconditionally whether or not it is null. It's easiest to do
3351 -- this with a recursive procedure:
3352
3353 else
3354 declare
3355 function Get_Known_Bound (J : Nat) return Node_Id;
3356 -- Returns the lower bound determined by operands J .. NN
3357
3358 ---------------------
3359 -- Get_Known_Bound --
3360 ---------------------
3361
3362 function Get_Known_Bound (J : Nat) return Node_Id is
df46b832 3363 begin
0ac73189 3364 if Is_Fixed_Length (J) or else J = NN then
683af98c 3365 return New_Copy_Tree (Opnd_Low_Bound (J));
70482933
RK
3366
3367 else
df46b832 3368 return
9b16cb57 3369 Make_If_Expression (Loc,
df46b832
AC
3370 Expressions => New_List (
3371
3372 Make_Op_Ne (Loc,
e4494292
RD
3373 Left_Opnd =>
3374 New_Occurrence_Of (Var_Length (J), Loc),
3375 Right_Opnd =>
3376 Make_Integer_Literal (Loc, 0)),
df46b832 3377
683af98c 3378 New_Copy_Tree (Opnd_Low_Bound (J)),
df46b832 3379 Get_Known_Bound (J + 1)));
70482933 3380 end if;
df46b832 3381 end Get_Known_Bound;
70482933 3382
df46b832 3383 begin
191fcb3a 3384 Ent := Make_Temporary (Loc, 'L');
df46b832 3385
d0f8d157 3386 Append_To (Actions,
df46b832
AC
3387 Make_Object_Declaration (Loc,
3388 Defining_Identifier => Ent,
3389 Constant_Present => True,
0ac73189 3390 Object_Definition => New_Occurrence_Of (Ityp, Loc),
d0f8d157 3391 Expression => Get_Known_Bound (1)));
df46b832 3392
e4494292 3393 Low_Bound := New_Occurrence_Of (Ent, Loc);
df46b832
AC
3394 end;
3395 end if;
70482933 3396
a6b13d32
AC
3397 pragma Assert (Present (Low_Bound));
3398
76c597a1
AC
3399 -- Now we can safely compute the upper bound, normally
3400 -- Low_Bound + Length - 1.
0ac73189
AC
3401
3402 High_Bound :=
cc6f5d75
AC
3403 To_Ityp
3404 (Make_Op_Add (Loc,
683af98c 3405 Left_Opnd => To_Artyp (New_Copy_Tree (Low_Bound)),
cc6f5d75
AC
3406 Right_Opnd =>
3407 Make_Op_Subtract (Loc,
683af98c 3408 Left_Opnd => New_Copy_Tree (Aggr_Length (NN)),
cc6f5d75 3409 Right_Opnd => Make_Artyp_Literal (1))));
0ac73189 3410
59262ebb 3411 -- Note that calculation of the high bound may cause overflow in some
bded454f
RD
3412 -- very weird cases, so in the general case we need an overflow check on
3413 -- the high bound. We can avoid this for the common case of string types
3414 -- and other types whose index is Positive, since we chose a wider range
54740d7d
AC
3415 -- for the arithmetic type. If checks are suppressed we do not set the
3416 -- flag, and possibly superfluous warnings will be omitted.
76c597a1 3417
54740d7d
AC
3418 if Istyp /= Standard_Positive
3419 and then not Overflow_Checks_Suppressed (Istyp)
3420 then
59262ebb
AC
3421 Activate_Overflow_Check (High_Bound);
3422 end if;
76c597a1
AC
3423
3424 -- Handle the exceptional case where the result is null, in which case
a29262fd
AC
3425 -- case the bounds come from the last operand (so that we get the proper
3426 -- bounds if the last operand is super-flat).
3427
0ac73189 3428 if Result_May_Be_Null then
88a27b18 3429 Low_Bound :=
9b16cb57 3430 Make_If_Expression (Loc,
88a27b18
AC
3431 Expressions => New_List (
3432 Make_Op_Eq (Loc,
683af98c 3433 Left_Opnd => New_Copy_Tree (Aggr_Length (NN)),
88a27b18
AC
3434 Right_Opnd => Make_Artyp_Literal (0)),
3435 Last_Opnd_Low_Bound,
3436 Low_Bound));
3437
0ac73189 3438 High_Bound :=
9b16cb57 3439 Make_If_Expression (Loc,
0ac73189
AC
3440 Expressions => New_List (
3441 Make_Op_Eq (Loc,
683af98c 3442 Left_Opnd => New_Copy_Tree (Aggr_Length (NN)),
fa969310 3443 Right_Opnd => Make_Artyp_Literal (0)),
a29262fd 3444 Last_Opnd_High_Bound,
0ac73189
AC
3445 High_Bound));
3446 end if;
3447
d0f8d157
AC
3448 -- Here is where we insert the saved up actions
3449
3450 Insert_Actions (Cnode, Actions, Suppress => All_Checks);
3451
602a7ec0
AC
3452 -- Now we construct an array object with appropriate bounds. We mark
3453 -- the target as internal to prevent useless initialization when
e526d0c7
AC
3454 -- Initialize_Scalars is enabled. Also since this is the actual result
3455 -- entity, we make sure we have debug information for the result.
70482933 3456
263bb393
AC
3457 Subtyp_Ind :=
3458 Make_Subtype_Indication (Loc,
3459 Subtype_Mark => New_Occurrence_Of (Atyp, Loc),
3460 Constraint =>
3461 Make_Index_Or_Discriminant_Constraint (Loc,
3462 Constraints => New_List (
3463 Make_Range (Loc,
3464 Low_Bound => Low_Bound,
3465 High_Bound => High_Bound))));
3466
191fcb3a 3467 Ent := Make_Temporary (Loc, 'S');
923ecd0e
HK
3468 Set_Is_Internal (Ent);
3469 Set_Debug_Info_Needed (Ent);
70482933 3470
263bb393
AC
3471 -- If we are concatenating strings and the current scope already uses
3472 -- the secondary stack, allocate the resulting string also on the
3473 -- secondary stack to avoid putting too much pressure on the primary
3474 -- stack.
3475 -- Don't do this if -gnatd.h is set, as this will break the wrapping of
3476 -- Cnode in an Expression_With_Actions, see Expand_N_Op_Concat.
3477
3478 if Atyp = Standard_String
3479 and then Uses_Sec_Stack (Current_Scope)
3480 and then RTE_Available (RE_SS_Pool)
3481 and then not Debug_Flag_Dot_H
3482 then
3483 -- Generate:
3484 -- subtype Axx is ...;
3485 -- type Ayy is access Axx;
3486 -- Rxx : Ayy := new <subtype> [storage_pool = ss_pool];
3487 -- Sxx : <subtype> renames Rxx.all;
3488
3489 declare
3490 Alloc : Node_Id;
3491 ConstrT : constant Entity_Id := Make_Temporary (Loc, 'A');
3492 Acc_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
3493 Temp : Entity_Id;
3494
3495 begin
3496 Insert_Action (Cnode,
3497 Make_Subtype_Declaration (Loc,
3498 Defining_Identifier => ConstrT,
3499 Subtype_Indication => Subtyp_Ind),
3500 Suppress => All_Checks);
3501 Freeze_Itype (ConstrT, Cnode);
3502
3503 Insert_Action (Cnode,
3504 Make_Full_Type_Declaration (Loc,
3505 Defining_Identifier => Acc_Typ,
3506 Type_Definition =>
3507 Make_Access_To_Object_Definition (Loc,
3508 Subtype_Indication => New_Occurrence_Of (ConstrT, Loc))),
3509 Suppress => All_Checks);
3510 Alloc :=
3511 Make_Allocator (Loc,
3512 Expression => New_Occurrence_Of (ConstrT, Loc));
0ea52908
BD
3513
3514 -- Allocate on the secondary stack. This is currently done
3515 -- only for type String, which normally doesn't have default
3516 -- initialization, but we need to Set_No_Initialization in case
3517 -- of Initialize_Scalars or Normalize_Scalars; otherwise, the
3518 -- allocator will get transformed and will not use the secondary
3519 -- stack.
3520
263bb393
AC
3521 Set_Storage_Pool (Alloc, RTE (RE_SS_Pool));
3522 Set_Procedure_To_Call (Alloc, RTE (RE_SS_Allocate));
0ea52908 3523 Set_No_Initialization (Alloc);
263bb393
AC
3524
3525 Temp := Make_Temporary (Loc, 'R', Alloc);
3526 Insert_Action (Cnode,
3527 Make_Object_Declaration (Loc,
3528 Defining_Identifier => Temp,
3529 Object_Definition => New_Occurrence_Of (Acc_Typ, Loc),
3530 Expression => Alloc),
3531 Suppress => All_Checks);
3532
3533 Insert_Action (Cnode,
3534 Make_Object_Renaming_Declaration (Loc,
3535 Defining_Identifier => Ent,
3536 Subtype_Mark => New_Occurrence_Of (ConstrT, Loc),
3537 Name =>
3538 Make_Explicit_Dereference (Loc,
3539 Prefix => New_Occurrence_Of (Temp, Loc))),
3540 Suppress => All_Checks);
3541 end;
3542 else
3543 -- If the bound is statically known to be out of range, we do not
3544 -- want to abort, we want a warning and a runtime constraint error.
3545 -- Note that we have arranged that the result will not be treated as
3546 -- a static constant, so we won't get an illegality during this
3547 -- insertion.
86b3d0d5
AC
3548 -- We also enable checks (in particular range checks) in case the
3549 -- bounds of Subtyp_Ind are out of range.
263bb393
AC
3550
3551 Insert_Action (Cnode,
3552 Make_Object_Declaration (Loc,
3553 Defining_Identifier => Ent,
86b3d0d5 3554 Object_Definition => Subtyp_Ind));
263bb393 3555 end if;
df46b832 3556
d1f453b7
RD
3557 -- If the result of the concatenation appears as the initializing
3558 -- expression of an object declaration, we can just rename the
3559 -- result, rather than copying it.
3560
3561 Set_OK_To_Rename (Ent);
3562
76c597a1
AC
3563 -- Catch the static out of range case now
3564
3565 if Raises_Constraint_Error (High_Bound) then
3566 raise Concatenation_Error;
3567 end if;
3568
df46b832
AC
3569 -- Now we will generate the assignments to do the actual concatenation
3570
bded454f
RD
3571 -- There is one case in which we will not do this, namely when all the
3572 -- following conditions are met:
3573
3574 -- The result type is Standard.String
3575
3576 -- There are nine or fewer retained (non-null) operands
3577
2df23f66
AC
3578 -- The optimization level is -O0 or the debug flag gnatd.C is set,
3579 -- and the debug flag gnatd.c is not set.
bded454f
RD
3580
3581 -- The corresponding System.Concat_n.Str_Concat_n routine is
3582 -- available in the run time.
3583
bded454f
RD
3584 -- If all these conditions are met then we generate a call to the
3585 -- relevant concatenation routine. The purpose of this is to avoid
3586 -- undesirable code bloat at -O0.
3587
2df23f66
AC
3588 -- If the concatenation is within the declaration of a library-level
3589 -- object, we call the built-in concatenation routines to prevent code
3590 -- bloat, regardless of the optimization level. This is space efficient
3591 -- and prevents linking problems when units are compiled with different
3592 -- optimization levels.
3593
bded454f
RD
3594 if Atyp = Standard_String
3595 and then NN in 2 .. 9
2df23f66
AC
3596 and then (((Optimization_Level = 0 or else Debug_Flag_Dot_CC)
3597 and then not Debug_Flag_Dot_C)
3598 or else Library_Level_Target)
bded454f
RD
3599 then
3600 declare
3601 RR : constant array (Nat range 2 .. 9) of RE_Id :=
3602 (RE_Str_Concat_2,
3603 RE_Str_Concat_3,
3604 RE_Str_Concat_4,
3605 RE_Str_Concat_5,
3606 RE_Str_Concat_6,
3607 RE_Str_Concat_7,
3608 RE_Str_Concat_8,
3609 RE_Str_Concat_9);
3610
3611 begin
3612 if RTE_Available (RR (NN)) then
3613 declare
3614 Opnds : constant List_Id :=
3615 New_List (New_Occurrence_Of (Ent, Loc));
3616
3617 begin
3618 for J in 1 .. NN loop
3619 if Is_List_Member (Operands (J)) then
3620 Remove (Operands (J));
3621 end if;
3622
3623 if Base_Type (Etype (Operands (J))) = Ctyp then
3624 Append_To (Opnds,
3625 Make_Aggregate (Loc,
3626 Component_Associations => New_List (
3627 Make_Component_Association (Loc,
3628 Choices => New_List (
3629 Make_Integer_Literal (Loc, 1)),
3630 Expression => Operands (J)))));
3631
3632 else
3633 Append_To (Opnds, Operands (J));
3634 end if;
3635 end loop;
3636
3637 Insert_Action (Cnode,
3638 Make_Procedure_Call_Statement (Loc,
e4494292 3639 Name => New_Occurrence_Of (RTE (RR (NN)), Loc),
bded454f
RD
3640 Parameter_Associations => Opnds));
3641
e4494292 3642 Result := New_Occurrence_Of (Ent, Loc);
bded454f
RD
3643 goto Done;
3644 end;
3645 end if;
3646 end;
3647 end if;
3648
3649 -- Not special case so generate the assignments
3650
76c597a1
AC
3651 Known_Non_Null_Operand_Seen := False;
3652
df46b832
AC
3653 for J in 1 .. NN loop
3654 declare
3655 Lo : constant Node_Id :=
3656 Make_Op_Add (Loc,
683af98c 3657 Left_Opnd => To_Artyp (New_Copy_Tree (Low_Bound)),
df46b832
AC
3658 Right_Opnd => Aggr_Length (J - 1));
3659
3660 Hi : constant Node_Id :=
3661 Make_Op_Add (Loc,
683af98c 3662 Left_Opnd => To_Artyp (New_Copy_Tree (Low_Bound)),
df46b832
AC
3663 Right_Opnd =>
3664 Make_Op_Subtract (Loc,
3665 Left_Opnd => Aggr_Length (J),
fa969310 3666 Right_Opnd => Make_Artyp_Literal (1)));
70482933 3667
df46b832 3668 begin
fdac1f80
AC
3669 -- Singleton case, simple assignment
3670
3671 if Base_Type (Etype (Operands (J))) = Ctyp then
76c597a1 3672 Known_Non_Null_Operand_Seen := True;
df46b832
AC
3673 Insert_Action (Cnode,
3674 Make_Assignment_Statement (Loc,
3675 Name =>
3676 Make_Indexed_Component (Loc,
3677 Prefix => New_Occurrence_Of (Ent, Loc),
fdac1f80 3678 Expressions => New_List (To_Ityp (Lo))),
df46b832
AC
3679 Expression => Operands (J)),
3680 Suppress => All_Checks);
70482933 3681
76c597a1
AC
3682 -- Array case, slice assignment, skipped when argument is fixed
3683 -- length and known to be null.
fdac1f80 3684
76c597a1
AC
3685 elsif (not Is_Fixed_Length (J)) or else (Fixed_Length (J) > 0) then
3686 declare
3687 Assign : Node_Id :=
3688 Make_Assignment_Statement (Loc,
3689 Name =>
3690 Make_Slice (Loc,
3691 Prefix =>
3692 New_Occurrence_Of (Ent, Loc),
3693 Discrete_Range =>
3694 Make_Range (Loc,
3695 Low_Bound => To_Ityp (Lo),
3696 High_Bound => To_Ityp (Hi))),
3697 Expression => Operands (J));
3698 begin
3699 if Is_Fixed_Length (J) then
3700 Known_Non_Null_Operand_Seen := True;
3701
3702 elsif not Known_Non_Null_Operand_Seen then
3703
3704 -- Here if operand length is not statically known and no
3705 -- operand known to be non-null has been processed yet.
3706 -- If operand length is 0, we do not need to perform the
3707 -- assignment, and we must avoid the evaluation of the
3708 -- high bound of the slice, since it may underflow if the
3709 -- low bound is Ityp'First.
3710
3711 Assign :=
3712 Make_Implicit_If_Statement (Cnode,
39ade2f9 3713 Condition =>
76c597a1 3714 Make_Op_Ne (Loc,
39ade2f9 3715 Left_Opnd =>
76c597a1
AC
3716 New_Occurrence_Of (Var_Length (J), Loc),
3717 Right_Opnd => Make_Integer_Literal (Loc, 0)),
39ade2f9 3718 Then_Statements => New_List (Assign));
76c597a1 3719 end if;
fa969310 3720
76c597a1
AC
3721 Insert_Action (Cnode, Assign, Suppress => All_Checks);
3722 end;
df46b832
AC
3723 end if;
3724 end;
3725 end loop;
70482933 3726
0ac73189
AC
3727 -- Finally we build the result, which is a reference to the array object
3728
e4494292 3729 Result := New_Occurrence_Of (Ent, Loc);
70482933 3730
df46b832 3731 <<Done>>
a6b13d32 3732 pragma Assert (Present (Result));
df46b832 3733 Rewrite (Cnode, Result);
fdac1f80
AC
3734 Analyze_And_Resolve (Cnode, Atyp);
3735
3736 exception
3737 when Concatenation_Error =>
76c597a1
AC
3738
3739 -- Kill warning generated for the declaration of the static out of
3740 -- range high bound, and instead generate a Constraint_Error with
3741 -- an appropriate specific message.
3742
3743 Kill_Dead_Code (Declaration_Node (Entity (High_Bound)));
3744 Apply_Compile_Time_Constraint_Error
3745 (N => Cnode,
324ac540 3746 Msg => "concatenation result upper bound out of range??",
76c597a1 3747 Reason => CE_Range_Check_Failed);
fdac1f80 3748 end Expand_Concatenate;
70482933 3749
f6194278
RD
3750 ---------------------------------------------------
3751 -- Expand_Membership_Minimize_Eliminate_Overflow --
3752 ---------------------------------------------------
3753
3754 procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id) is
3755 pragma Assert (Nkind (N) = N_In);
3756 -- Despite the name, this routine applies only to N_In, not to
3757 -- N_Not_In. The latter is always rewritten as not (X in Y).
3758
71fb4dc8
AC
3759 Result_Type : constant Entity_Id := Etype (N);
3760 -- Capture result type, may be a derived boolean type
3761
b6b5cca8
AC
3762 Loc : constant Source_Ptr := Sloc (N);
3763 Lop : constant Node_Id := Left_Opnd (N);
3764 Rop : constant Node_Id := Right_Opnd (N);
3765
3766 -- Note: there are many referencs to Etype (Lop) and Etype (Rop). It
3767 -- is thus tempting to capture these values, but due to the rewrites
3768 -- that occur as a result of overflow checking, these values change
3769 -- as we go along, and it is safe just to always use Etype explicitly.
f6194278
RD
3770
3771 Restype : constant Entity_Id := Etype (N);
3772 -- Save result type
3773
3774 Lo, Hi : Uint;
d8192289 3775 -- Bounds in Minimize calls, not used currently
f6194278
RD
3776
3777 LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
0964be07 3778 -- Entity for Long_Long_Integer'Base
f6194278
RD
3779
3780 begin
a7f1b24f 3781 Minimize_Eliminate_Overflows (Lop, Lo, Hi, Top_Level => False);
f6194278
RD
3782
3783 -- If right operand is a subtype name, and the subtype name has no
3784 -- predicate, then we can just replace the right operand with an
3785 -- explicit range T'First .. T'Last, and use the explicit range code.
3786
b6b5cca8
AC
3787 if Nkind (Rop) /= N_Range
3788 and then No (Predicate_Function (Etype (Rop)))
3789 then
3790 declare
3791 Rtyp : constant Entity_Id := Etype (Rop);
3792 begin
3793 Rewrite (Rop,
3794 Make_Range (Loc,
cc6f5d75 3795 Low_Bound =>
b6b5cca8
AC
3796 Make_Attribute_Reference (Loc,
3797 Attribute_Name => Name_First,
e4494292 3798 Prefix => New_Occurrence_Of (Rtyp, Loc)),
b6b5cca8
AC
3799 High_Bound =>
3800 Make_Attribute_Reference (Loc,
3801 Attribute_Name => Name_Last,
e4494292 3802 Prefix => New_Occurrence_Of (Rtyp, Loc))));
b6b5cca8
AC
3803 Analyze_And_Resolve (Rop, Rtyp, Suppress => All_Checks);
3804 end;
f6194278
RD
3805 end if;
3806
3807 -- Here for the explicit range case. Note that the bounds of the range
3808 -- have not been processed for minimized or eliminated checks.
3809
3810 if Nkind (Rop) = N_Range then
a7f1b24f 3811 Minimize_Eliminate_Overflows
b6b5cca8 3812 (Low_Bound (Rop), Lo, Hi, Top_Level => False);
a7f1b24f 3813 Minimize_Eliminate_Overflows
c7e152b5 3814 (High_Bound (Rop), Lo, Hi, Top_Level => False);
f6194278
RD
3815
3816 -- We have A in B .. C, treated as A >= B and then A <= C
3817
3818 -- Bignum case
3819
b6b5cca8 3820 if Is_RTE (Etype (Lop), RE_Bignum)
f6194278
RD
3821 or else Is_RTE (Etype (Low_Bound (Rop)), RE_Bignum)
3822 or else Is_RTE (Etype (High_Bound (Rop)), RE_Bignum)
3823 then
3824 declare
3825 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3826 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
71fb4dc8
AC
3827 L : constant Entity_Id :=
3828 Make_Defining_Identifier (Loc, Name_uL);
f6194278
RD
3829 Lopnd : constant Node_Id := Convert_To_Bignum (Lop);
3830 Lbound : constant Node_Id :=
3831 Convert_To_Bignum (Low_Bound (Rop));
3832 Hbound : constant Node_Id :=
3833 Convert_To_Bignum (High_Bound (Rop));
3834
71fb4dc8
AC
3835 -- Now we rewrite the membership test node to look like
3836
3837 -- do
3838 -- Bnn : Result_Type;
3839 -- declare
3840 -- M : Mark_Id := SS_Mark;
3841 -- L : Bignum := Lopnd;
3842 -- begin
3843 -- Bnn := Big_GE (L, Lbound) and then Big_LE (L, Hbound)
3844 -- SS_Release (M);
3845 -- end;
3846 -- in
3847 -- Bnn
3848 -- end
f6194278
RD
3849
3850 begin
71fb4dc8
AC
3851 -- Insert declaration of L into declarations of bignum block
3852
f6194278
RD
3853 Insert_After
3854 (Last (Declarations (Blk)),
3855 Make_Object_Declaration (Loc,
71fb4dc8 3856 Defining_Identifier => L,
f6194278
RD
3857 Object_Definition =>
3858 New_Occurrence_Of (RTE (RE_Bignum), Loc),
3859 Expression => Lopnd));
3860
71fb4dc8
AC
3861 -- Insert assignment to Bnn into expressions of bignum block
3862
f6194278
RD
3863 Insert_Before
3864 (First (Statements (Handled_Statement_Sequence (Blk))),
3865 Make_Assignment_Statement (Loc,
3866 Name => New_Occurrence_Of (Bnn, Loc),
3867 Expression =>
3868 Make_And_Then (Loc,
cc6f5d75 3869 Left_Opnd =>
f6194278
RD
3870 Make_Function_Call (Loc,
3871 Name =>
3872 New_Occurrence_Of (RTE (RE_Big_GE), Loc),
71fb4dc8
AC
3873 Parameter_Associations => New_List (
3874 New_Occurrence_Of (L, Loc),
3875 Lbound)),
cc6f5d75 3876
f6194278
RD
3877 Right_Opnd =>
3878 Make_Function_Call (Loc,
3879 Name =>
71fb4dc8
AC
3880 New_Occurrence_Of (RTE (RE_Big_LE), Loc),
3881 Parameter_Associations => New_List (
3882 New_Occurrence_Of (L, Loc),
3883 Hbound)))));
f6194278 3884
71fb4dc8 3885 -- Now rewrite the node
f6194278 3886
71fb4dc8
AC
3887 Rewrite (N,
3888 Make_Expression_With_Actions (Loc,
3889 Actions => New_List (
3890 Make_Object_Declaration (Loc,
3891 Defining_Identifier => Bnn,
3892 Object_Definition =>
3893 New_Occurrence_Of (Result_Type, Loc)),
3894 Blk),
3895 Expression => New_Occurrence_Of (Bnn, Loc)));
3896 Analyze_And_Resolve (N, Result_Type);
f6194278
RD
3897 return;
3898 end;
3899
3900 -- Here if no bignums around
3901
3902 else
3903 -- Case where types are all the same
3904
b6b5cca8 3905 if Base_Type (Etype (Lop)) = Base_Type (Etype (Low_Bound (Rop)))
f6194278 3906 and then
b6b5cca8 3907 Base_Type (Etype (Lop)) = Base_Type (Etype (High_Bound (Rop)))
f6194278
RD
3908 then
3909 null;
3910
3911 -- If types are not all the same, it means that we have rewritten
3912 -- at least one of them to be of type Long_Long_Integer, and we
3913 -- will convert the other operands to Long_Long_Integer.
3914
3915 else
3916 Convert_To_And_Rewrite (LLIB, Lop);
71fb4dc8
AC
3917 Set_Analyzed (Lop, False);
3918 Analyze_And_Resolve (Lop, LLIB);
3919
3920 -- For the right operand, avoid unnecessary recursion into
3921 -- this routine, we know that overflow is not possible.
f6194278
RD
3922
3923 Convert_To_And_Rewrite (LLIB, Low_Bound (Rop));
3924 Convert_To_And_Rewrite (LLIB, High_Bound (Rop));
3925 Set_Analyzed (Rop, False);
71fb4dc8 3926 Analyze_And_Resolve (Rop, LLIB, Suppress => Overflow_Check);
f6194278
RD
3927 end if;
3928
3929 -- Now the three operands are of the same signed integer type,
b6b5cca8
AC
3930 -- so we can use the normal expansion routine for membership,
3931 -- setting the flag to prevent recursion into this procedure.
f6194278
RD
3932
3933 Set_No_Minimize_Eliminate (N);
3934 Expand_N_In (N);
3935 end if;
3936
3937 -- Right operand is a subtype name and the subtype has a predicate. We
f6636994
AC
3938 -- have to make sure the predicate is checked, and for that we need to
3939 -- use the standard N_In circuitry with appropriate types.
f6194278
RD
3940
3941 else
b6b5cca8 3942 pragma Assert (Present (Predicate_Function (Etype (Rop))));
f6194278
RD
3943
3944 -- If types are "right", just call Expand_N_In preventing recursion
3945
b6b5cca8 3946 if Base_Type (Etype (Lop)) = Base_Type (Etype (Rop)) then
f6194278
RD
3947 Set_No_Minimize_Eliminate (N);
3948 Expand_N_In (N);
3949
3950 -- Bignum case
3951
b6b5cca8 3952 elsif Is_RTE (Etype (Lop), RE_Bignum) then
f6194278 3953
71fb4dc8 3954 -- For X in T, we want to rewrite our node as
f6194278 3955
71fb4dc8
AC
3956 -- do
3957 -- Bnn : Result_Type;
f6194278 3958
71fb4dc8
AC
3959 -- declare
3960 -- M : Mark_Id := SS_Mark;
3961 -- Lnn : Long_Long_Integer'Base
3962 -- Nnn : Bignum;
f6194278 3963
71fb4dc8
AC
3964 -- begin
3965 -- Nnn := X;
3966
3967 -- if not Bignum_In_LLI_Range (Nnn) then
3968 -- Bnn := False;
3969 -- else
3970 -- Lnn := From_Bignum (Nnn);
3971 -- Bnn :=
3972 -- Lnn in LLIB (T'Base'First) .. LLIB (T'Base'Last)
3973 -- and then T'Base (Lnn) in T;
3974 -- end if;
cc6f5d75
AC
3975
3976 -- SS_Release (M);
71fb4dc8
AC
3977 -- end
3978 -- in
3979 -- Bnn
3980 -- end
f6194278 3981
f6636994 3982 -- A bit gruesome, but there doesn't seem to be a simpler way
f6194278
RD
3983
3984 declare
b6b5cca8
AC
3985 Blk : constant Node_Id := Make_Bignum_Block (Loc);
3986 Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
3987 Lnn : constant Entity_Id := Make_Temporary (Loc, 'L', N);
3988 Nnn : constant Entity_Id := Make_Temporary (Loc, 'N', N);
71fb4dc8
AC
3989 T : constant Entity_Id := Etype (Rop);
3990 TB : constant Entity_Id := Base_Type (T);
b6b5cca8 3991 Nin : Node_Id;
f6194278
RD
3992
3993 begin
71fb4dc8 3994 -- Mark the last membership operation to prevent recursion
f6194278
RD
3995
3996 Nin :=
3997 Make_In (Loc,
f6636994
AC
3998 Left_Opnd => Convert_To (TB, New_Occurrence_Of (Lnn, Loc)),
3999 Right_Opnd => New_Occurrence_Of (T, Loc));
f6194278
RD
4000 Set_No_Minimize_Eliminate (Nin);
4001
4002 -- Now decorate the block
4003
4004 Insert_After
4005 (Last (Declarations (Blk)),
4006 Make_Object_Declaration (Loc,
4007 Defining_Identifier => Lnn,
4008 Object_Definition => New_Occurrence_Of (LLIB, Loc)));
4009
4010 Insert_After
4011 (Last (Declarations (Blk)),
4012 Make_Object_Declaration (Loc,
4013 Defining_Identifier => Nnn,
4014 Object_Definition =>
4015 New_Occurrence_Of (RTE (RE_Bignum), Loc)));
4016
4017 Insert_List_Before
4018 (First (Statements (Handled_Statement_Sequence (Blk))),
4019 New_List (
4020 Make_Assignment_Statement (Loc,
4021 Name => New_Occurrence_Of (Nnn, Loc),
4022 Expression => Relocate_Node (Lop)),
4023
8b1011c0 4024 Make_Implicit_If_Statement (N,
f6194278 4025 Condition =>
71fb4dc8
AC
4026 Make_Op_Not (Loc,
4027 Right_Opnd =>
4028 Make_Function_Call (Loc,
4029 Name =>
4030 New_Occurrence_Of
4031 (RTE (RE_Bignum_In_LLI_Range), Loc),
4032 Parameter_Associations => New_List (
4033 New_Occurrence_Of (Nnn, Loc)))),
f6194278
RD
4034
4035 Then_Statements => New_List (
4036 Make_Assignment_Statement (Loc,
4037 Name => New_Occurrence_Of (Bnn, Loc),
4038 Expression =>
4039 New_Occurrence_Of (Standard_False, Loc))),
4040
4041 Else_Statements => New_List (
4042 Make_Assignment_Statement (Loc,
4043 Name => New_Occurrence_Of (Lnn, Loc),
4044 Expression =>
4045 Make_Function_Call (Loc,
4046 Name =>
4047 New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
4048 Parameter_Associations => New_List (
4049 New_Occurrence_Of (Nnn, Loc)))),
4050
4051 Make_Assignment_Statement (Loc,
71fb4dc8 4052 Name => New_Occurrence_Of (Bnn, Loc),
f6194278
RD
4053 Expression =>
4054 Make_And_Then (Loc,
71fb4dc8 4055 Left_Opnd =>
f6194278 4056 Make_In (Loc,
71fb4dc8 4057 Left_Opnd => New_Occurrence_Of (Lnn, Loc),
f6194278 4058 Right_Opnd =>
71fb4dc8
AC
4059 Make_Range (Loc,
4060 Low_Bound =>
4061 Convert_To (LLIB,
4062 Make_Attribute_Reference (Loc,
4063 Attribute_Name => Name_First,
4064 Prefix =>
4065 New_Occurrence_Of (TB, Loc))),
4066
4067 High_Bound =>
4068 Convert_To (LLIB,
4069 Make_Attribute_Reference (Loc,
4070 Attribute_Name => Name_Last,
4071 Prefix =>
4072 New_Occurrence_Of (TB, Loc))))),
4073
f6194278
RD
4074 Right_Opnd => Nin))))));
4075
71fb4dc8 4076 -- Now we can do the rewrite
f6194278 4077
71fb4dc8
AC
4078 Rewrite (N,
4079 Make_Expression_With_Actions (Loc,
4080 Actions => New_List (
4081 Make_Object_Declaration (Loc,
4082 Defining_Identifier => Bnn,
4083 Object_Definition =>
4084 New_Occurrence_Of (Result_Type, Loc)),
4085 Blk),
4086 Expression => New_Occurrence_Of (Bnn, Loc)));
4087 Analyze_And_Resolve (N, Result_Type);
f6194278
RD
4088 return;
4089 end;
4090
4091 -- Not bignum case, but types don't match (this means we rewrote the
b6b5cca8 4092 -- left operand to be Long_Long_Integer).
f6194278
RD
4093
4094 else
b6b5cca8 4095 pragma Assert (Base_Type (Etype (Lop)) = LLIB);
f6194278 4096
71fb4dc8
AC
4097 -- We rewrite the membership test as (where T is the type with
4098 -- the predicate, i.e. the type of the right operand)
f6194278 4099
71fb4dc8
AC
4100 -- Lop in LLIB (T'Base'First) .. LLIB (T'Base'Last)
4101 -- and then T'Base (Lop) in T
f6194278
RD
4102
4103 declare
71fb4dc8
AC
4104 T : constant Entity_Id := Etype (Rop);
4105 TB : constant Entity_Id := Base_Type (T);
f6194278
RD
4106 Nin : Node_Id;
4107
4108 begin
4109 -- The last membership test is marked to prevent recursion
4110
4111 Nin :=
4112 Make_In (Loc,
71fb4dc8
AC
4113 Left_Opnd => Convert_To (TB, Duplicate_Subexpr (Lop)),
4114 Right_Opnd => New_Occurrence_Of (T, Loc));
f6194278
RD
4115 Set_No_Minimize_Eliminate (Nin);
4116
4117 -- Now do the rewrite
4118
4119 Rewrite (N,
4120 Make_And_Then (Loc,
71fb4dc8 4121 Left_Opnd =>
f6194278
RD
4122 Make_In (Loc,
4123 Left_Opnd => Lop,
4124 Right_Opnd =>
71fb4dc8
AC
4125 Make_Range (Loc,
4126 Low_Bound =>
4127 Convert_To (LLIB,
4128 Make_Attribute_Reference (Loc,
4129 Attribute_Name => Name_First,
cc6f5d75
AC
4130 Prefix =>
4131 New_Occurrence_Of (TB, Loc))),
71fb4dc8
AC
4132 High_Bound =>
4133 Convert_To (LLIB,
4134 Make_Attribute_Reference (Loc,
4135 Attribute_Name => Name_Last,
cc6f5d75
AC
4136 Prefix =>
4137 New_Occurrence_Of (TB, Loc))))),
f6194278 4138 Right_Opnd => Nin));
71fb4dc8
AC
4139 Set_Analyzed (N, False);
4140 Analyze_And_Resolve (N, Restype);
f6194278
RD
4141 end;
4142 end if;
4143 end if;
4144 end Expand_Membership_Minimize_Eliminate_Overflow;
4145
c7a494c9
AC
4146 ---------------------------------
4147 -- Expand_Nonbinary_Modular_Op --
4148 ---------------------------------
05dbb83f 4149
c7a494c9 4150 procedure Expand_Nonbinary_Modular_Op (N : Node_Id) is
05dbb83f
AC
4151 Loc : constant Source_Ptr := Sloc (N);
4152 Typ : constant Entity_Id := Etype (N);
4153
4154 procedure Expand_Modular_Addition;
c7a494c9 4155 -- Expand the modular addition, handling the special case of adding a
05dbb83f
AC
4156 -- constant.
4157
4158 procedure Expand_Modular_Op;
4159 -- Compute the general rule: (lhs OP rhs) mod Modulus
4160
4161 procedure Expand_Modular_Subtraction;
c7a494c9 4162 -- Expand the modular addition, handling the special case of subtracting
05dbb83f
AC
4163 -- a constant.
4164
4165 -----------------------------
4166 -- Expand_Modular_Addition --
4167 -----------------------------
4168
4169 procedure Expand_Modular_Addition is
4170 begin
4171 -- If this is not the addition of a constant then compute it using
4172 -- the general rule: (lhs + rhs) mod Modulus
4173
4174 if Nkind (Right_Opnd (N)) /= N_Integer_Literal then
4175 Expand_Modular_Op;
4176
4177 -- If this is an addition of a constant, convert it to a subtraction
4178 -- plus a conditional expression since we can compute it faster than
4179 -- computing the modulus.
4180
4181 -- modMinusRhs = Modulus - rhs
4182 -- if lhs < modMinusRhs then lhs + rhs
4183 -- else lhs - modMinusRhs
4184
4185 else
4186 declare
4187 Mod_Minus_Right : constant Uint :=
4188 Modulus (Typ) - Intval (Right_Opnd (N));
4189
4190 Exprs : constant List_Id := New_List;
4191 Cond_Expr : constant Node_Id := New_Op_Node (N_Op_Lt, Loc);
4192 Then_Expr : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
4193 Else_Expr : constant Node_Id := New_Op_Node (N_Op_Subtract,
4194 Loc);
4195 begin
dfd2da00
ES
4196 -- To prevent spurious visibility issues, convert all
4197 -- operands to Standard.Unsigned.
4198
05dbb83f 4199 Set_Left_Opnd (Cond_Expr,
dfd2da00
ES
4200 Unchecked_Convert_To (Standard_Unsigned,
4201 New_Copy_Tree (Left_Opnd (N))));
05dbb83f
AC
4202 Set_Right_Opnd (Cond_Expr,
4203 Make_Integer_Literal (Loc, Mod_Minus_Right));
4204 Append_To (Exprs, Cond_Expr);
4205
4206 Set_Left_Opnd (Then_Expr,
4207 Unchecked_Convert_To (Standard_Unsigned,
4208 New_Copy_Tree (Left_Opnd (N))));
4209 Set_Right_Opnd (Then_Expr,
4210 Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
4211 Append_To (Exprs, Then_Expr);
4212
4213 Set_Left_Opnd (Else_Expr,
4214 Unchecked_Convert_To (Standard_Unsigned,
4215 New_Copy_Tree (Left_Opnd (N))));
4216 Set_Right_Opnd (Else_Expr,
4217 Make_Integer_Literal (Loc, Mod_Minus_Right));
4218 Append_To (Exprs, Else_Expr);
4219
4220 Rewrite (N,
4221 Unchecked_Convert_To (Typ,
4222 Make_If_Expression (Loc, Expressions => Exprs)));
4223 end;
4224 end if;
4225 end Expand_Modular_Addition;
4226
4227 -----------------------
4228 -- Expand_Modular_Op --
4229 -----------------------
4230
4231 procedure Expand_Modular_Op is
4232 Op_Expr : constant Node_Id := New_Op_Node (Nkind (N), Loc);
4233 Mod_Expr : constant Node_Id := New_Op_Node (N_Op_Mod, Loc);
4234
184d0451
ES
4235 Target_Type : Entity_Id;
4236
05dbb83f 4237 begin
c7a494c9
AC
4238 -- Convert nonbinary modular type operands into integer values. Thus
4239 -- we avoid never-ending loops expanding them, and we also ensure
4240 -- the back end never receives nonbinary modular type expressions.
05dbb83f 4241
4a08c95c 4242 if Nkind (N) in N_Op_And | N_Op_Or | N_Op_Xor then
05dbb83f
AC
4243 Set_Left_Opnd (Op_Expr,
4244 Unchecked_Convert_To (Standard_Unsigned,
4245 New_Copy_Tree (Left_Opnd (N))));
4246 Set_Right_Opnd (Op_Expr,
4247 Unchecked_Convert_To (Standard_Unsigned,
4248 New_Copy_Tree (Right_Opnd (N))));
4249 Set_Left_Opnd (Mod_Expr,
4250 Unchecked_Convert_To (Standard_Integer, Op_Expr));
3e720c96 4251
05dbb83f 4252 else
c7862167
HK
4253 -- If the modulus of the type is larger than Integer'Last use a
4254 -- larger type for the operands, to prevent spurious constraint
4255 -- errors on large legal literals of the type.
184d0451 4256
1c3e11c0 4257 if Modulus (Etype (N)) > Int (Integer'Last) then
cbe3b8d4 4258 Target_Type := Standard_Long_Long_Integer;
184d0451
ES
4259 else
4260 Target_Type := Standard_Integer;
4261 end if;
4262
05dbb83f 4263 Set_Left_Opnd (Op_Expr,
184d0451 4264 Unchecked_Convert_To (Target_Type,
05dbb83f
AC
4265 New_Copy_Tree (Left_Opnd (N))));
4266 Set_Right_Opnd (Op_Expr,
184d0451 4267 Unchecked_Convert_To (Target_Type,
05dbb83f 4268 New_Copy_Tree (Right_Opnd (N))));
9fb1e654
AC
4269
4270 -- Link this node to the tree to analyze it
4271
a4f4dbdb
AC
4272 -- If the parent node is an expression with actions we link it to
4273 -- N since otherwise Force_Evaluation cannot identify if this node
4274 -- comes from the Expression and rejects generating the temporary.
9fb1e654
AC
4275
4276 if Nkind (Parent (N)) = N_Expression_With_Actions then
4277 Set_Parent (Op_Expr, N);
4278
4279 -- Common case
4280
4281 else
4282 Set_Parent (Op_Expr, Parent (N));
4283 end if;
4284
4285 Analyze (Op_Expr);
4286
4287 -- Force generating a temporary because in the expansion of this
4288 -- expression we may generate code that performs this computation
4289 -- several times.
4290
4291 Force_Evaluation (Op_Expr, Mode => Strict);
4292
05dbb83f
AC
4293 Set_Left_Opnd (Mod_Expr, Op_Expr);
4294 end if;
4295
4296 Set_Right_Opnd (Mod_Expr,
4297 Make_Integer_Literal (Loc, Modulus (Typ)));
4298
4299 Rewrite (N,
4300 Unchecked_Convert_To (Typ, Mod_Expr));
4301 end Expand_Modular_Op;
4302
4303 --------------------------------
4304 -- Expand_Modular_Subtraction --
4305 --------------------------------
4306
4307 procedure Expand_Modular_Subtraction is
4308 begin
4309 -- If this is not the addition of a constant then compute it using
4310 -- the general rule: (lhs + rhs) mod Modulus
4311
4312 if Nkind (Right_Opnd (N)) /= N_Integer_Literal then
4313 Expand_Modular_Op;
4314
4315 -- If this is an addition of a constant, convert it to a subtraction
4316 -- plus a conditional expression since we can compute it faster than
4317 -- computing the modulus.
4318
4319 -- modMinusRhs = Modulus - rhs
4320 -- if lhs < rhs then lhs + modMinusRhs
4321 -- else lhs - rhs
4322
4323 else
4324 declare
4325 Mod_Minus_Right : constant Uint :=
4326 Modulus (Typ) - Intval (Right_Opnd (N));
4327
4328 Exprs : constant List_Id := New_List;
4329 Cond_Expr : constant Node_Id := New_Op_Node (N_Op_Lt, Loc);
4330 Then_Expr : constant Node_Id := New_Op_Node (N_Op_Add, Loc);
4331 Else_Expr : constant Node_Id := New_Op_Node (N_Op_Subtract,
4332 Loc);
4333 begin
4334 Set_Left_Opnd (Cond_Expr,
dfd2da00
ES
4335 Unchecked_Convert_To (Standard_Unsigned,
4336 New_Copy_Tree (Left_Opnd (N))));
05dbb83f
AC
4337 Set_Right_Opnd (Cond_Expr,
4338 Make_Integer_Literal (Loc, Intval (Right_Opnd (N))));
4339 Append_To (Exprs, Cond_Expr);
4340
4341 Set_Left_Opnd (Then_Expr,
4342 Unchecked_Convert_To (Standard_Unsigned,
4343 New_Copy_Tree (Left_Opnd (N))));
4344 Set_Right_Opnd (Then_Expr,
4345 Make_Integer_Literal (Loc, Mod_Minus_Right));
4346 Append_To (Exprs, Then_Expr);
4347
4348 Set_Left_Opnd (Else_Expr,
4349 Unchecked_Convert_To (Standard_Unsigned,
4350 New_Copy_Tree (Left_Opnd (N))));
4351 Set_Right_Opnd (Else_Expr,
4352 Unchecked_Convert_To (Standard_Unsigned,
4353 New_Copy_Tree (Right_Opnd (N))));
4354 Append_To (Exprs, Else_Expr);
4355
4356 Rewrite (N,
4357 Unchecked_Convert_To (Typ,
4358 Make_If_Expression (Loc, Expressions => Exprs)));
4359 end;
4360 end if;
4361 end Expand_Modular_Subtraction;
4362
c7a494c9 4363 -- Start of processing for Expand_Nonbinary_Modular_Op
05dbb83f
AC
4364
4365 begin
f4ac86dd
PMR
4366 -- No action needed if front-end expansion is not required or if we
4367 -- have a binary modular operand.
05dbb83f 4368
f4ac86dd 4369 if not Expand_Nonbinary_Modular_Ops
05dbb83f
AC
4370 or else not Non_Binary_Modulus (Typ)
4371 then
4372 return;
4373 end if;
4374
4375 case Nkind (N) is
4376 when N_Op_Add =>
4377 Expand_Modular_Addition;
4378
4379 when N_Op_Subtract =>
4380 Expand_Modular_Subtraction;
4381
4382 when N_Op_Minus =>
3e720c96 4383
05dbb83f
AC
4384 -- Expand -expr into (0 - expr)
4385
4386 Rewrite (N,
4387 Make_Op_Subtract (Loc,
4388 Left_Opnd => Make_Integer_Literal (Loc, 0),
4389 Right_Opnd => Right_Opnd (N)));
4390 Analyze_And_Resolve (N, Typ);
4391
4392 when others =>
4393 Expand_Modular_Op;
4394 end case;
4395
4396 Analyze_And_Resolve (N, Typ);
c7a494c9 4397 end Expand_Nonbinary_Modular_Op;
05dbb83f 4398
70482933
RK
4399 ------------------------
4400 -- Expand_N_Allocator --
4401 ------------------------
4402
4403 procedure Expand_N_Allocator (N : Node_Id) is
8b1011c0
AC
4404 Etyp : constant Entity_Id := Etype (Expression (N));
4405 Loc : constant Source_Ptr := Sloc (N);
4406 PtrT : constant Entity_Id := Etype (N);
70482933 4407
26bff3d9
JM
4408 procedure Rewrite_Coextension (N : Node_Id);
4409 -- Static coextensions have the same lifetime as the entity they
8fc789c8 4410 -- constrain. Such occurrences can be rewritten as aliased objects
26bff3d9 4411 -- and their unrestricted access used instead of the coextension.
0669bebe 4412
8aec446b 4413 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id;
507ed3fd 4414 -- Given a constrained array type E, returns a node representing the
22862ba6
JM
4415 -- code to compute a close approximation of the size in storage elements
4416 -- for the given type; for indexes that are modular types we compute
4417 -- 'Last - First (instead of 'Length) because for large arrays computing
4418 -- 'Last -'First + 1 causes overflow. This is done without using the
4419 -- attribute 'Size_In_Storage_Elements (which malfunctions for large
7c2a44ae 4420 -- sizes ???).
8aec446b 4421
26bff3d9
JM
4422 -------------------------
4423 -- Rewrite_Coextension --
4424 -------------------------
4425
4426 procedure Rewrite_Coextension (N : Node_Id) is
e5a22243
AC
4427 Temp_Id : constant Node_Id := Make_Temporary (Loc, 'C');
4428 Temp_Decl : Node_Id;
26bff3d9 4429
df3e68b1 4430 begin
26bff3d9
JM
4431 -- Generate:
4432 -- Cnn : aliased Etyp;
4433
df3e68b1
HK
4434 Temp_Decl :=
4435 Make_Object_Declaration (Loc,
4436 Defining_Identifier => Temp_Id,
243cae0a
AC
4437 Aliased_Present => True,
4438 Object_Definition => New_Occurrence_Of (Etyp, Loc));
26bff3d9 4439
26bff3d9 4440 if Nkind (Expression (N)) = N_Qualified_Expression then
df3e68b1 4441 Set_Expression (Temp_Decl, Expression (Expression (N)));
0669bebe 4442 end if;
26bff3d9 4443
e5a22243 4444 Insert_Action (N, Temp_Decl);
26bff3d9
JM
4445 Rewrite (N,
4446 Make_Attribute_Reference (Loc,
243cae0a 4447 Prefix => New_Occurrence_Of (Temp_Id, Loc),
26bff3d9
JM
4448 Attribute_Name => Name_Unrestricted_Access));
4449
4450 Analyze_And_Resolve (N, PtrT);
4451 end Rewrite_Coextension;
0669bebe 4452
8aec446b
AC
4453 ------------------------------
4454 -- Size_In_Storage_Elements --
4455 ------------------------------
4456
4457 function Size_In_Storage_Elements (E : Entity_Id) return Node_Id is
4458 begin
4459 -- Logically this just returns E'Max_Size_In_Storage_Elements.
4460 -- However, the reason for the existence of this function is
4461 -- to construct a test for sizes too large, which means near the
4462 -- 32-bit limit on a 32-bit machine, and precisely the trouble
4463 -- is that we get overflows when sizes are greater than 2**31.
4464
507ed3fd 4465 -- So what we end up doing for array types is to use the expression:
8aec446b
AC
4466
4467 -- number-of-elements * component_type'Max_Size_In_Storage_Elements
4468
46202729 4469 -- which avoids this problem. All this is a bit bogus, but it does
8aec446b
AC
4470 -- mean we catch common cases of trying to allocate arrays that
4471 -- are too large, and which in the absence of a check results in
4472 -- undetected chaos ???
4473
507ed3fd 4474 declare
22862ba6 4475 Idx : Node_Id := First_Index (E);
507ed3fd 4476 Len : Node_Id;
a6b13d32 4477 Res : Node_Id := Empty;
8aec446b 4478
507ed3fd
AC
4479 begin
4480 for J in 1 .. Number_Dimensions (E) loop
22862ba6
JM
4481
4482 if not Is_Modular_Integer_Type (Etype (Idx)) then
4483 Len :=
4484 Make_Attribute_Reference (Loc,
4485 Prefix => New_Occurrence_Of (E, Loc),
4486 Attribute_Name => Name_Length,
4487 Expressions => New_List
4488 (Make_Integer_Literal (Loc, J)));
4489
4490 -- For indexes that are modular types we cannot generate code
4491 -- to compute 'Length since for large arrays 'Last -'First + 1
4492 -- causes overflow; therefore we compute 'Last - 'First (which
4493 -- is not the exact number of components but it is valid for
7c2a44ae 4494 -- the purpose of this runtime check on 32-bit targets).
22862ba6
JM
4495
4496 else
4497 declare
4498 Len_Minus_1_Expr : Node_Id;
4499 Test_Gt : Node_Id;
4500
4501 begin
4502 Test_Gt :=
4503 Make_Op_Gt (Loc,
4504 Make_Attribute_Reference (Loc,
4505 Prefix => New_Occurrence_Of (E, Loc),
4506 Attribute_Name => Name_Last,
4507 Expressions =>
4508 New_List (Make_Integer_Literal (Loc, J))),
4509 Make_Attribute_Reference (Loc,
4510 Prefix => New_Occurrence_Of (E, Loc),
4511 Attribute_Name => Name_First,
4512 Expressions =>
4513 New_List (Make_Integer_Literal (Loc, J))));
4514
4515 Len_Minus_1_Expr :=
4516 Convert_To (Standard_Unsigned,
4517 Make_Op_Subtract (Loc,
4518 Make_Attribute_Reference (Loc,
4519 Prefix => New_Occurrence_Of (E, Loc),
4520 Attribute_Name => Name_Last,
4521 Expressions =>
4522 New_List
4523 (Make_Integer_Literal (Loc, J))),
4524 Make_Attribute_Reference (Loc,
4525 Prefix => New_Occurrence_Of (E, Loc),
4526 Attribute_Name => Name_First,
4527 Expressions =>
4528 New_List
4529 (Make_Integer_Literal (Loc, J)))));
4530
4531 -- Handle superflat arrays, i.e. arrays with such bounds
7c2a44ae 4532 -- as 4 .. 2, to ensure that the result is correct.
22862ba6
JM
4533
4534 -- Generate:
4535 -- (if X'Last > X'First then X'Last - X'First else 0)
4536
4537 Len :=
4538 Make_If_Expression (Loc,
4539 Expressions => New_List (
4540 Test_Gt,
4541 Len_Minus_1_Expr,
4542 Make_Integer_Literal (Loc, Uint_0)));
4543 end;
4544 end if;
8aec446b 4545
507ed3fd
AC
4546 if J = 1 then
4547 Res := Len;
8aec446b 4548
507ed3fd 4549 else
a6b13d32 4550 pragma Assert (Present (Res));
507ed3fd
AC
4551 Res :=
4552 Make_Op_Multiply (Loc,
4553 Left_Opnd => Res,
4554 Right_Opnd => Len);
4555 end if;
22862ba6
JM
4556
4557 Next_Index (Idx);
507ed3fd 4558 end loop;
8aec446b 4559
8aec446b 4560 return
507ed3fd
AC
4561 Make_Op_Multiply (Loc,
4562 Left_Opnd => Len,
4563 Right_Opnd =>
4564 Make_Attribute_Reference (Loc,
4565 Prefix => New_Occurrence_Of (Component_Type (E), Loc),
4566 Attribute_Name => Name_Max_Size_In_Storage_Elements));
4567 end;
8aec446b
AC
4568 end Size_In_Storage_Elements;
4569
8b1011c0
AC
4570 -- Local variables
4571
70861157 4572 Dtyp : constant Entity_Id := Available_View (Designated_Type (PtrT));
8b1011c0
AC
4573 Desig : Entity_Id;
4574 Nod : Node_Id;
4575 Pool : Entity_Id;
4576 Rel_Typ : Entity_Id;
4577 Temp : Entity_Id;
4578
0669bebe
GB
4579 -- Start of processing for Expand_N_Allocator
4580
70482933 4581 begin
b3889fff 4582 -- Warn on the presence of an allocator of an anonymous access type when
31fde973 4583 -- enabled, except when it's an object declaration at library level.
b3889fff
JS
4584
4585 if Warn_On_Anonymous_Allocators
4586 and then Ekind (PtrT) = E_Anonymous_Access_Type
943c82d7
JS
4587 and then not (Is_Library_Level_Entity (PtrT)
4588 and then Nkind (Associated_Node_For_Itype (PtrT)) =
4589 N_Object_Declaration)
b3889fff 4590 then
2d6f6e08 4591 Error_Msg_N ("??use of an anonymous access type allocator", N);
b3889fff
JS
4592 end if;
4593
072c5071 4594 -- RM E.2.2(17). We enforce that the expected type of an allocator
0964be07
BD
4595 -- shall not be a remote access-to-class-wide-limited-private type.
4596 -- We probably shouldn't be doing this legality check during expansion,
4597 -- but this is only an issue for Annex E users, and is unlikely to be a
4598 -- problem in practice.
70482933
RK
4599
4600 Validate_Remote_Access_To_Class_Wide_Type (N);
4601
ca5af305
AC
4602 -- Processing for anonymous access-to-controlled types. These access
4603 -- types receive a special finalization master which appears in the
4604 -- declarations of the enclosing semantic unit. This expansion is done
84f4072a
JM
4605 -- now to ensure that any additional types generated by this routine or
4606 -- Expand_Allocator_Expression inherit the proper type attributes.
ca5af305 4607
84f4072a 4608 if (Ekind (PtrT) = E_Anonymous_Access_Type
533369aa 4609 or else (Is_Itype (PtrT) and then No (Finalization_Master (PtrT))))
ca5af305
AC
4610 and then Needs_Finalization (Dtyp)
4611 then
8b1011c0
AC
4612 -- Detect the allocation of an anonymous controlled object where the
4613 -- type of the context is named. For example:
4614
4615 -- procedure Proc (Ptr : Named_Access_Typ);
4616 -- Proc (new Designated_Typ);
4617
4618 -- Regardless of the anonymous-to-named access type conversion, the
4619 -- lifetime of the object must be associated with the named access
0088ba92 4620 -- type. Use the finalization-related attributes of this type.
8b1011c0 4621
4a08c95c
AC
4622 if Nkind (Parent (N)) in N_Type_Conversion
4623 | N_Unchecked_Type_Conversion
4624 and then Ekind (Etype (Parent (N))) in E_Access_Subtype
4625 | E_Access_Type
4626 | E_General_Access_Type
8b1011c0
AC
4627 then
4628 Rel_Typ := Etype (Parent (N));
4629 else
4630 Rel_Typ := Empty;
4631 end if;
4632
b254da66 4633 -- Anonymous access-to-controlled types allocate on the global pool.
535a8637 4634 -- Note that this is a "root type only" attribute.
ca5af305 4635
535a8637 4636 if No (Associated_Storage_Pool (PtrT)) then
8b1011c0 4637 if Present (Rel_Typ) then
7a5b62b0 4638 Set_Associated_Storage_Pool
24d4b3d5 4639 (Root_Type (PtrT), Associated_Storage_Pool (Rel_Typ));
8b1011c0 4640 else
7a5b62b0 4641 Set_Associated_Storage_Pool
24d4b3d5 4642 (Root_Type (PtrT), RTE (RE_Global_Pool_Object));
8b1011c0 4643 end if;
ca5af305
AC
4644 end if;
4645
4646 -- The finalization master must be inserted and analyzed as part of
5114f3ff 4647 -- the current semantic unit. Note that the master is updated when
24d4b3d5
AC
4648 -- analysis changes current units. Note that this is a "root type
4649 -- only" attribute.
ca5af305 4650
5114f3ff 4651 if Present (Rel_Typ) then
24d4b3d5
AC
4652 Set_Finalization_Master
4653 (Root_Type (PtrT), Finalization_Master (Rel_Typ));
5114f3ff 4654 else
32b794c8 4655 Build_Anonymous_Master (Root_Type (PtrT));
ca5af305
AC
4656 end if;
4657 end if;
4658
4659 -- Set the storage pool and find the appropriate version of Allocate to
8417f4b2
AC
4660 -- call. Do not overwrite the storage pool if it is already set, which
4661 -- can happen for build-in-place function returns (see
200b7162 4662 -- Exp_Ch4.Expand_N_Extended_Return_Statement).
70482933 4663
200b7162
BD
4664 if No (Storage_Pool (N)) then
4665 Pool := Associated_Storage_Pool (Root_Type (PtrT));
70482933 4666
200b7162
BD
4667 if Present (Pool) then
4668 Set_Storage_Pool (N, Pool);
fbf5a39b 4669
200b7162 4670 if Is_RTE (Pool, RE_SS_Pool) then
abbfd698 4671 Check_Restriction (No_Secondary_Stack, N);
535a8637 4672 Set_Procedure_To_Call (N, RTE (RE_SS_Allocate));
fbf5a39b 4673
a8551b5f
AC
4674 -- In the case of an allocator for a simple storage pool, locate
4675 -- and save a reference to the pool type's Allocate routine.
4676
4677 elsif Present (Get_Rep_Pragma
f6205414 4678 (Etype (Pool), Name_Simple_Storage_Pool_Type))
a8551b5f
AC
4679 then
4680 declare
a8551b5f 4681 Pool_Type : constant Entity_Id := Base_Type (Etype (Pool));
260359e3 4682 Alloc_Op : Entity_Id;
a8551b5f 4683 begin
260359e3 4684 Alloc_Op := Get_Name_Entity_Id (Name_Allocate);
a8551b5f
AC
4685 while Present (Alloc_Op) loop
4686 if Scope (Alloc_Op) = Scope (Pool_Type)
4687 and then Present (First_Formal (Alloc_Op))
4688 and then Etype (First_Formal (Alloc_Op)) = Pool_Type
4689 then
4690 Set_Procedure_To_Call (N, Alloc_Op);
a8551b5f 4691 exit;
260359e3
AC
4692 else
4693 Alloc_Op := Homonym (Alloc_Op);
a8551b5f 4694 end if;
a8551b5f
AC
4695 end loop;
4696 end;
4697
200b7162
BD
4698 elsif Is_Class_Wide_Type (Etype (Pool)) then
4699 Set_Procedure_To_Call (N, RTE (RE_Allocate_Any));
4700
4701 else
4702 Set_Procedure_To_Call (N,
4703 Find_Prim_Op (Etype (Pool), Name_Allocate));
4704 end if;
70482933
RK
4705 end if;
4706 end if;
4707
685094bf
RD
4708 -- Under certain circumstances we can replace an allocator by an access
4709 -- to statically allocated storage. The conditions, as noted in AARM
4710 -- 3.10 (10c) are as follows:
70482933
RK
4711
4712 -- Size and initial value is known at compile time
4713 -- Access type is access-to-constant
4714
fbf5a39b
AC
4715 -- The allocator is not part of a constraint on a record component,
4716 -- because in that case the inserted actions are delayed until the
4717 -- record declaration is fully analyzed, which is too late for the
4718 -- analysis of the rewritten allocator.
4719
70482933
RK
4720 if Is_Access_Constant (PtrT)
4721 and then Nkind (Expression (N)) = N_Qualified_Expression
4722 and then Compile_Time_Known_Value (Expression (Expression (N)))
243cae0a
AC
4723 and then Size_Known_At_Compile_Time
4724 (Etype (Expression (Expression (N))))
fbf5a39b 4725 and then not Is_Record_Type (Current_Scope)
70482933
RK
4726 then
4727 -- Here we can do the optimization. For the allocator
4728
4729 -- new x'(y)
4730
4731 -- We insert an object declaration
4732
4733 -- Tnn : aliased x := y;
4734
685094bf
RD
4735 -- and replace the allocator by Tnn'Unrestricted_Access. Tnn is
4736 -- marked as requiring static allocation.
70482933 4737
df3e68b1 4738 Temp := Make_Temporary (Loc, 'T', Expression (Expression (N)));
70482933
RK
4739 Desig := Subtype_Mark (Expression (N));
4740
4741 -- If context is constrained, use constrained subtype directly,
8fc789c8 4742 -- so that the constant is not labelled as having a nominally
70482933
RK
4743 -- unconstrained subtype.
4744
0da2c8ac
AC
4745 if Entity (Desig) = Base_Type (Dtyp) then
4746 Desig := New_Occurrence_Of (Dtyp, Loc);
70482933
RK
4747 end if;
4748
4749 Insert_Action (N,
4750 Make_Object_Declaration (Loc,
4751 Defining_Identifier => Temp,
4752 Aliased_Present => True,
4753 Constant_Present => Is_Access_Constant (PtrT),
4754 Object_Definition => Desig,
4755 Expression => Expression (Expression (N))));
4756
4757 Rewrite (N,
4758 Make_Attribute_Reference (Loc,
243cae0a 4759 Prefix => New_Occurrence_Of (Temp, Loc),
70482933
RK
4760 Attribute_Name => Name_Unrestricted_Access));
4761
4762 Analyze_And_Resolve (N, PtrT);
4763
685094bf 4764 -- We set the variable as statically allocated, since we don't want
a90bd866 4765 -- it going on the stack of the current procedure.
70482933
RK
4766
4767 Set_Is_Statically_Allocated (Temp);
4768 return;
4769 end if;
4770
0669bebe
GB
4771 -- Same if the allocator is an access discriminant for a local object:
4772 -- instead of an allocator we create a local value and constrain the
308e6f3a 4773 -- enclosing object with the corresponding access attribute.
0669bebe 4774
26bff3d9
JM
4775 if Is_Static_Coextension (N) then
4776 Rewrite_Coextension (N);
0669bebe
GB
4777 return;
4778 end if;
4779
8aec446b
AC
4780 -- Check for size too large, we do this because the back end misses
4781 -- proper checks here and can generate rubbish allocation calls when
4782 -- we are near the limit. We only do this for the 32-bit address case
4783 -- since that is from a practical point of view where we see a problem.
4784
4785 if System_Address_Size = 32
4786 and then not Storage_Checks_Suppressed (PtrT)
4787 and then not Storage_Checks_Suppressed (Dtyp)
4788 and then not Storage_Checks_Suppressed (Etyp)
4789 then
4790 -- The check we want to generate should look like
4791
4792 -- if Etyp'Max_Size_In_Storage_Elements > 3.5 gigabytes then
4793 -- raise Storage_Error;
4794 -- end if;
4795
308e6f3a 4796 -- where 3.5 gigabytes is a constant large enough to accommodate any
507ed3fd
AC
4797 -- reasonable request for. But we can't do it this way because at
4798 -- least at the moment we don't compute this attribute right, and
4799 -- can silently give wrong results when the result gets large. Since
4800 -- this is all about large results, that's bad, so instead we only
205c14b0 4801 -- apply the check for constrained arrays, and manually compute the
507ed3fd 4802 -- value of the attribute ???
8aec446b 4803
22862ba6
JM
4804 -- The check on No_Initialization is used here to prevent generating
4805 -- this runtime check twice when the allocator is locally replaced by
7c2a44ae 4806 -- the expander with another one.
22862ba6
JM
4807
4808 if Is_Array_Type (Etyp) and then not No_Initialization (N) then
4809 declare
4810 Cond : Node_Id;
4811 Ins_Nod : Node_Id := N;
4812 Siz_Typ : Entity_Id := Etyp;
4813 Expr : Node_Id;
4814
4815 begin
4816 -- For unconstrained array types initialized with a qualified
4817 -- expression we use its type to perform this check
4818
4819 if not Is_Constrained (Etyp)
4820 and then not No_Initialization (N)
4821 and then Nkind (Expression (N)) = N_Qualified_Expression
4822 then
4823 Expr := Expression (Expression (N));
4824 Siz_Typ := Etype (Expression (Expression (N)));
4825
4826 -- If the qualified expression has been moved to an internal
4827 -- temporary (to remove side effects) then we must insert
4828 -- the runtime check before its declaration to ensure that
4829 -- the check is performed before the execution of the code
4830 -- computing the qualified expression.
4831
4832 if Nkind (Expr) = N_Identifier
4833 and then Is_Internal_Name (Chars (Expr))
4834 and then
4835 Nkind (Parent (Entity (Expr))) = N_Object_Declaration
4836 then
4837 Ins_Nod := Parent (Entity (Expr));
4838 else
4839 Ins_Nod := Expr;
4840 end if;
4841 end if;
4842
4843 if Is_Constrained (Siz_Typ)
4844 and then Ekind (Siz_Typ) /= E_String_Literal_Subtype
4845 then
7c2a44ae
PT
4846 -- For CCG targets, the largest array may have up to 2**31-1
4847 -- components (i.e. 2 gigabytes if each array component is
4848 -- one byte). This ensures that fat pointer fields do not
22862ba6 4849 -- overflow, since they are 32-bit integer types, and also
7c2a44ae 4850 -- ensures that 'Length can be computed at run time.
22862ba6
JM
4851
4852 if Modify_Tree_For_C then
4853 Cond :=
4854 Make_Op_Gt (Loc,
4855 Left_Opnd => Size_In_Storage_Elements (Siz_Typ),
4856 Right_Opnd => Make_Integer_Literal (Loc,
4857 Uint_2 ** 31 - Uint_1));
4858
4859 -- For native targets the largest object is 3.5 gigabytes
4860
4861 else
4862 Cond :=
4863 Make_Op_Gt (Loc,
4864 Left_Opnd => Size_In_Storage_Elements (Siz_Typ),
4865 Right_Opnd => Make_Integer_Literal (Loc,
4866 Uint_7 * (Uint_2 ** 29)));
4867 end if;
4868
4869 Insert_Action (Ins_Nod,
4870 Make_Raise_Storage_Error (Loc,
4871 Condition => Cond,
4872 Reason => SE_Object_Too_Large));
4873
4874 if Entity (Cond) = Standard_True then
4875 Error_Msg_N
4876 ("object too large: Storage_Error will be raised at "
4877 & "run time??", N);
4878 end if;
4879 end if;
4880 end;
507ed3fd 4881 end if;
8aec446b
AC
4882 end if;
4883
b3181992
GD
4884 -- If no storage pool has been specified, or the storage pool
4885 -- is System.Pool_Global.Global_Pool_Object, and the restriction
b3b26ace
AC
4886 -- No_Standard_Allocators_After_Elaboration is present, then generate
4887 -- a call to Elaboration_Allocators.Check_Standard_Allocator.
4888
4889 if Nkind (N) = N_Allocator
b3181992
GD
4890 and then (No (Storage_Pool (N))
4891 or else Is_RTE (Storage_Pool (N), RE_Global_Pool_Object))
b3b26ace
AC
4892 and then Restriction_Active (No_Standard_Allocators_After_Elaboration)
4893 then
4894 Insert_Action (N,
4895 Make_Procedure_Call_Statement (Loc,
4896 Name =>
4897 New_Occurrence_Of (RTE (RE_Check_Standard_Allocator), Loc)));
4898 end if;
4899
4bfab79a 4900 -- Handle case of qualified expression (other than optimization above)
0da2c8ac 4901
70482933 4902 if Nkind (Expression (N)) = N_Qualified_Expression then
fbf5a39b 4903 Expand_Allocator_Expression (N);
26bff3d9
JM
4904 return;
4905 end if;
fbf5a39b 4906
26bff3d9
JM
4907 -- If the allocator is for a type which requires initialization, and
4908 -- there is no initial value (i.e. operand is a subtype indication
685094bf
RD
4909 -- rather than a qualified expression), then we must generate a call to
4910 -- the initialization routine using an expressions action node:
70482933 4911
26bff3d9 4912 -- [Pnnn : constant ptr_T := new (T); Init (Pnnn.all,...); Pnnn]
70482933 4913
26bff3d9
JM
4914 -- Here ptr_T is the pointer type for the allocator, and T is the
4915 -- subtype of the allocator. A special case arises if the designated
4916 -- type of the access type is a task or contains tasks. In this case
4917 -- the call to Init (Temp.all ...) is replaced by code that ensures
4918 -- that tasks get activated (see Exp_Ch9.Build_Task_Allocate_Block
6be44a9a 4919 -- for details). In addition, if the type T is a task type, then the
26bff3d9 4920 -- first argument to Init must be converted to the task record type.
70482933 4921
26bff3d9 4922 declare
529749b9 4923 T : constant Entity_Id := Etype (Expression (N));
df3e68b1
HK
4924 Args : List_Id;
4925 Decls : List_Id;
4926 Decl : Node_Id;
4927 Discr : Elmt_Id;
4928 Init : Entity_Id;
4929 Init_Arg1 : Node_Id;
2168d7cc 4930 Init_Call : Node_Id;
df3e68b1
HK
4931 Temp_Decl : Node_Id;
4932 Temp_Type : Entity_Id;
70482933 4933
26bff3d9 4934 begin
9e8102b3
EB
4935 -- Apply constraint checks against designated subtype (RM 4.8(10/2))
4936 -- but ignore the expression if the No_Initialization flag is set.
4bfab79a
EB
4937 -- Discriminant checks will be generated by the expansion below.
4938
9e8102b3 4939 if Is_Array_Type (Dtyp) and then not No_Initialization (N) then
4bfab79a
EB
4940 Apply_Constraint_Check (Expression (N), Dtyp, No_Sliding => True);
4941
4942 Apply_Predicate_Check (Expression (N), Dtyp);
4943
4944 if Nkind (Expression (N)) = N_Raise_Constraint_Error then
4945 Rewrite (N, New_Copy (Expression (N)));
4946 Set_Etype (N, PtrT);
4947 return;
4948 end if;
4949 end if;
4950
26bff3d9 4951 if No_Initialization (N) then
df3e68b1
HK
4952
4953 -- Even though this might be a simple allocation, create a custom
535a8637 4954 -- Allocate if the context requires it.
df3e68b1 4955
535a8637 4956 if Present (Finalization_Master (PtrT)) then
df3e68b1 4957 Build_Allocate_Deallocate_Proc
ca5af305 4958 (N => N,
df3e68b1
HK
4959 Is_Allocate => True);
4960 end if;
70482933 4961
40016fa7
HK
4962 -- Optimize the default allocation of an array object when pragma
4963 -- Initialize_Scalars or Normalize_Scalars is in effect. Construct an
4964 -- in-place initialization aggregate which may be convert into a fast
4965 -- memset by the backend.
529749b9
HK
4966
4967 elsif Init_Or_Norm_Scalars
4968 and then Is_Array_Type (T)
40016fa7
HK
4969
4970 -- The array must lack atomic components because they are treated
4971 -- as non-static, and as a result the backend will not initialize
4972 -- the memory in one go.
4973
529749b9 4974 and then not Has_Atomic_Components (T)
40016fa7
HK
4975
4976 -- The array must not be packed because the invalid values in
4977 -- System.Scalar_Values are multiples of Storage_Unit.
4978
529749b9 4979 and then not Is_Packed (T)
40016fa7
HK
4980
4981 -- The array must have static non-empty ranges, otherwise the
4982 -- backend cannot initialize the memory in one go.
4983
529749b9 4984 and then Has_Static_Non_Empty_Array_Bounds (T)
40016fa7
HK
4985
4986 -- The optimization is only relevant for arrays of scalar types
4987
529749b9 4988 and then Is_Scalar_Type (Component_Type (T))
40016fa7
HK
4989
4990 -- Similar to regular array initialization using a type init proc,
4991 -- predicate checks are not performed because the initialization
4992 -- values are intentionally invalid, and may violate the predicate.
4993
4994 and then not Has_Predicates (Component_Type (T))
4995
4996 -- The component type must have a single initialization value
4997
529749b9
HK
4998 and then Needs_Simple_Initialization
4999 (Typ => Component_Type (T),
5000 Consider_IS => True)
5001 then
5002 Set_Analyzed (N);
5003 Temp := Make_Temporary (Loc, 'P');
5004
5005 -- Generate:
5006 -- Temp : Ptr_Typ := new ...;
5007
5008 Insert_Action
5009 (Assoc_Node => N,
5010 Ins_Action =>
5011 Make_Object_Declaration (Loc,
5012 Defining_Identifier => Temp,
5013 Object_Definition => New_Occurrence_Of (PtrT, Loc),
5014 Expression => Relocate_Node (N)),
5015 Suppress => All_Checks);
5016
5017 -- Generate:
5018 -- Temp.all := (others => ...);
5019
5020 Insert_Action
5021 (Assoc_Node => N,
5022 Ins_Action =>
5023 Make_Assignment_Statement (Loc,
5024 Name =>
5025 Make_Explicit_Dereference (Loc,
5026 Prefix => New_Occurrence_Of (Temp, Loc)),
5027 Expression =>
5028 Get_Simple_Init_Val
5029 (Typ => T,
5030 N => N,
5031 Size => Esize (Component_Type (T)))),
5032 Suppress => All_Checks);
5033
5034 Rewrite (N, New_Occurrence_Of (Temp, Loc));
5035 Analyze_And_Resolve (N, PtrT);
5036
26bff3d9 5037 -- Case of no initialization procedure present
70482933 5038
26bff3d9 5039 elsif not Has_Non_Null_Base_Init_Proc (T) then
70482933 5040
26bff3d9 5041 -- Case of simple initialization required
70482933 5042
26bff3d9 5043 if Needs_Simple_Initialization (T) then
b4592168 5044 Check_Restriction (No_Default_Initialization, N);
26bff3d9
JM
5045 Rewrite (Expression (N),
5046 Make_Qualified_Expression (Loc,
5047 Subtype_Mark => New_Occurrence_Of (T, Loc),
b4592168 5048 Expression => Get_Simple_Init_Val (T, N)));
70482933 5049
26bff3d9
JM
5050 Analyze_And_Resolve (Expression (Expression (N)), T);
5051 Analyze_And_Resolve (Expression (N), T);
5052 Set_Paren_Count (Expression (Expression (N)), 1);
5053 Expand_N_Allocator (N);
70482933 5054
26bff3d9 5055 -- No initialization required
70482933
RK
5056
5057 else
b2c3160c
AC
5058 Build_Allocate_Deallocate_Proc
5059 (N => N,
5060 Is_Allocate => True);
26bff3d9 5061 end if;
70482933 5062
26bff3d9 5063 -- Case of initialization procedure present, must be called
70482933 5064
fa528281
JS
5065 -- NOTE: There is a *huge* amount of code duplication here from
5066 -- Build_Initialization_Call. We should probably refactor???
5067
26bff3d9 5068 else
b4592168 5069 Check_Restriction (No_Default_Initialization, N);
70482933 5070
b4592168
GD
5071 if not Restriction_Active (No_Default_Initialization) then
5072 Init := Base_Init_Proc (T);
5073 Nod := N;
191fcb3a 5074 Temp := Make_Temporary (Loc, 'P');
70482933 5075
b4592168 5076 -- Construct argument list for the initialization routine call
70482933 5077
df3e68b1 5078 Init_Arg1 :=
b4592168 5079 Make_Explicit_Dereference (Loc,
df3e68b1 5080 Prefix =>
e4494292 5081 New_Occurrence_Of (Temp, Loc));
df3e68b1
HK
5082
5083 Set_Assignment_OK (Init_Arg1);
b4592168 5084 Temp_Type := PtrT;
26bff3d9 5085
b4592168
GD
5086 -- The initialization procedure expects a specific type. if the
5087 -- context is access to class wide, indicate that the object
5088 -- being allocated has the right specific type.
70482933 5089
b4592168 5090 if Is_Class_Wide_Type (Dtyp) then
df3e68b1 5091 Init_Arg1 := Unchecked_Convert_To (T, Init_Arg1);
b4592168 5092 end if;
70482933 5093
b4592168
GD
5094 -- If designated type is a concurrent type or if it is private
5095 -- type whose definition is a concurrent type, the first
5096 -- argument in the Init routine has to be unchecked conversion
5097 -- to the corresponding record type. If the designated type is
243cae0a 5098 -- a derived type, also convert the argument to its root type.
20b5d666 5099
b4592168 5100 if Is_Concurrent_Type (T) then
df3e68b1
HK
5101 Init_Arg1 :=
5102 Unchecked_Convert_To (
5103 Corresponding_Record_Type (T), Init_Arg1);
70482933 5104
b4592168
GD
5105 elsif Is_Private_Type (T)
5106 and then Present (Full_View (T))
5107 and then Is_Concurrent_Type (Full_View (T))
5108 then
df3e68b1 5109 Init_Arg1 :=
b4592168 5110 Unchecked_Convert_To
df3e68b1 5111 (Corresponding_Record_Type (Full_View (T)), Init_Arg1);
70482933 5112
b4592168
GD
5113 elsif Etype (First_Formal (Init)) /= Base_Type (T) then
5114 declare
5115 Ftyp : constant Entity_Id := Etype (First_Formal (Init));
df3e68b1 5116
b4592168 5117 begin
df3e68b1
HK
5118 Init_Arg1 := OK_Convert_To (Etype (Ftyp), Init_Arg1);
5119 Set_Etype (Init_Arg1, Ftyp);
b4592168
GD
5120 end;
5121 end if;
70482933 5122
df3e68b1 5123 Args := New_List (Init_Arg1);
70482933 5124
b4592168
GD
5125 -- For the task case, pass the Master_Id of the access type as
5126 -- the value of the _Master parameter, and _Chain as the value
5127 -- of the _Chain parameter (_Chain will be defined as part of
5128 -- the generated code for the allocator).
70482933 5129
b4592168
GD
5130 -- In Ada 2005, the context may be a function that returns an
5131 -- anonymous access type. In that case the Master_Id has been
5132 -- created when expanding the function declaration.
70482933 5133
b4592168
GD
5134 if Has_Task (T) then
5135 if No (Master_Id (Base_Type (PtrT))) then
70482933 5136
b4592168
GD
5137 -- The designated type was an incomplete type, and the
5138 -- access type did not get expanded. Salvage it now.
70482933 5139
a7837c08
JM
5140 if Present (Parent (Base_Type (PtrT))) then
5141 Expand_N_Full_Type_Declaration
5142 (Parent (Base_Type (PtrT)));
3d67b239 5143
a7837c08
JM
5144 -- The only other possibility is an itype. For this
5145 -- case, the master must exist in the context. This is
5146 -- the case when the allocator initializes an access
5147 -- component in an init-proc.
3d67b239 5148
a7837c08
JM
5149 else
5150 pragma Assert (Is_Itype (PtrT));
5151 Build_Master_Renaming (PtrT, N);
b941ae65 5152 end if;
b4592168 5153 end if;
70482933 5154
b4592168
GD
5155 -- If the context of the allocator is a declaration or an
5156 -- assignment, we can generate a meaningful image for it,
5157 -- even though subsequent assignments might remove the
5158 -- connection between task and entity. We build this image
5159 -- when the left-hand side is a simple variable, a simple
5160 -- indexed assignment or a simple selected component.
5161
5162 if Nkind (Parent (N)) = N_Assignment_Statement then
5163 declare
5164 Nam : constant Node_Id := Name (Parent (N));
5165
5166 begin
5167 if Is_Entity_Name (Nam) then
5168 Decls :=
5169 Build_Task_Image_Decls
5170 (Loc,
5171 New_Occurrence_Of
5172 (Entity (Nam), Sloc (Nam)), T);
5173
4a08c95c
AC
5174 elsif Nkind (Nam) in N_Indexed_Component
5175 | N_Selected_Component
b4592168
GD
5176 and then Is_Entity_Name (Prefix (Nam))
5177 then
5178 Decls :=
5179 Build_Task_Image_Decls
5180 (Loc, Nam, Etype (Prefix (Nam)));
5181 else
5182 Decls := Build_Task_Image_Decls (Loc, T, T);
5183 end if;
5184 end;
70482933 5185
b4592168
GD
5186 elsif Nkind (Parent (N)) = N_Object_Declaration then
5187 Decls :=
5188 Build_Task_Image_Decls
5189 (Loc, Defining_Identifier (Parent (N)), T);
70482933 5190
b4592168
GD
5191 else
5192 Decls := Build_Task_Image_Decls (Loc, T, T);
5193 end if;
26bff3d9 5194
87dc09cb 5195 if Restriction_Active (No_Task_Hierarchy) then
3c1ecd7e
AC
5196 Append_To (Args,
5197 New_Occurrence_Of (RTE (RE_Library_Task_Level), Loc));
87dc09cb
AC
5198 else
5199 Append_To (Args,
e4494292 5200 New_Occurrence_Of
87dc09cb
AC
5201 (Master_Id (Base_Type (Root_Type (PtrT))), Loc));
5202 end if;
5203
b4592168 5204 Append_To (Args, Make_Identifier (Loc, Name_uChain));
26bff3d9 5205
b4592168
GD
5206 Decl := Last (Decls);
5207 Append_To (Args,
5208 New_Occurrence_Of (Defining_Identifier (Decl), Loc));
26bff3d9 5209
87dc09cb 5210 -- Has_Task is false, Decls not used
26bff3d9 5211
b4592168
GD
5212 else
5213 Decls := No_List;
26bff3d9
JM
5214 end if;
5215
b4592168
GD
5216 -- Add discriminants if discriminated type
5217
5218 declare
5219 Dis : Boolean := False;
dcd5fd67 5220 Typ : Entity_Id := Empty;
b4592168
GD
5221
5222 begin
5223 if Has_Discriminants (T) then
5224 Dis := True;
5225 Typ := T;
5226
bac5ba15
AC
5227 -- Type may be a private type with no visible discriminants
5228 -- in which case check full view if in scope, or the
5229 -- underlying_full_view if dealing with a type whose full
5230 -- view may be derived from a private type whose own full
5231 -- view has discriminants.
5232
5233 elsif Is_Private_Type (T) then
5234 if Present (Full_View (T))
5235 and then Has_Discriminants (Full_View (T))
5236 then
5237 Dis := True;
5238 Typ := Full_View (T);
5239
5240 elsif Present (Underlying_Full_View (T))
5241 and then Has_Discriminants (Underlying_Full_View (T))
5242 then
5243 Dis := True;
5244 Typ := Underlying_Full_View (T);
5245 end if;
20b5d666 5246 end if;
70482933 5247
b4592168 5248 if Dis then
26bff3d9 5249
b4592168 5250 -- If the allocated object will be constrained by the
685094bf
RD
5251 -- default values for discriminants, then build a subtype
5252 -- with those defaults, and change the allocated subtype
5253 -- to that. Note that this happens in fewer cases in Ada
5254 -- 2005 (AI-363).
26bff3d9 5255
b4592168
GD
5256 if not Is_Constrained (Typ)
5257 and then Present (Discriminant_Default_Value
df3e68b1 5258 (First_Discriminant (Typ)))
0791fbe9 5259 and then (Ada_Version < Ada_2005
cc96a1b8 5260 or else not
0fbcb11c
ES
5261 Object_Type_Has_Constrained_Partial_View
5262 (Typ, Current_Scope))
20b5d666 5263 then
b4592168 5264 Typ := Build_Default_Subtype (Typ, N);
e4494292 5265 Set_Expression (N, New_Occurrence_Of (Typ, Loc));
20b5d666
JM
5266 end if;
5267
b4592168
GD
5268 Discr := First_Elmt (Discriminant_Constraint (Typ));
5269 while Present (Discr) loop
5270 Nod := Node (Discr);
5271 Append (New_Copy_Tree (Node (Discr)), Args);
20b5d666 5272
b4592168
GD
5273 -- AI-416: when the discriminant constraint is an
5274 -- anonymous access type make sure an accessibility
5275 -- check is inserted if necessary (3.10.2(22.q/2))
20b5d666 5276
0791fbe9 5277 if Ada_Version >= Ada_2005
b4592168
GD
5278 and then
5279 Ekind (Etype (Nod)) = E_Anonymous_Access_Type
5280 then
e84e11ba
GD
5281 Apply_Accessibility_Check
5282 (Nod, Typ, Insert_Node => Nod);
b4592168 5283 end if;
20b5d666 5284
b4592168
GD
5285 Next_Elmt (Discr);
5286 end loop;
5287 end if;
5288 end;
70482933 5289
4b985e20 5290 -- We set the allocator as analyzed so that when we analyze
9b16cb57
RD
5291 -- the if expression node, we do not get an unwanted recursive
5292 -- expansion of the allocator expression.
70482933 5293
b4592168
GD
5294 Set_Analyzed (N, True);
5295 Nod := Relocate_Node (N);
70482933 5296
b4592168 5297 -- Here is the transformation:
ca5af305
AC
5298 -- input: new Ctrl_Typ
5299 -- output: Temp : constant Ctrl_Typ_Ptr := new Ctrl_Typ;
5300 -- Ctrl_TypIP (Temp.all, ...);
5301 -- [Deep_]Initialize (Temp.all);
70482933 5302
ca5af305
AC
5303 -- Here Ctrl_Typ_Ptr is the pointer type for the allocator, and
5304 -- is the subtype of the allocator.
70482933 5305
b4592168
GD
5306 Temp_Decl :=
5307 Make_Object_Declaration (Loc,
5308 Defining_Identifier => Temp,
5309 Constant_Present => True,
e4494292 5310 Object_Definition => New_Occurrence_Of (Temp_Type, Loc),
b4592168 5311 Expression => Nod);
70482933 5312
b4592168
GD
5313 Set_Assignment_OK (Temp_Decl);
5314 Insert_Action (N, Temp_Decl, Suppress => All_Checks);
70482933 5315
ca5af305 5316 Build_Allocate_Deallocate_Proc (Temp_Decl, True);
df3e68b1 5317
b4592168
GD
5318 -- If the designated type is a task type or contains tasks,
5319 -- create block to activate created tasks, and insert
5320 -- declaration for Task_Image variable ahead of call.
70482933 5321
b4592168
GD
5322 if Has_Task (T) then
5323 declare
5324 L : constant List_Id := New_List;
5325 Blk : Node_Id;
5326 begin
5327 Build_Task_Allocate_Block (L, Nod, Args);
5328 Blk := Last (L);
5329 Insert_List_Before (First (Declarations (Blk)), Decls);
5330 Insert_Actions (N, L);
5331 end;
70482933 5332
b4592168
GD
5333 else
5334 Insert_Action (N,
5335 Make_Procedure_Call_Statement (Loc,
e4494292 5336 Name => New_Occurrence_Of (Init, Loc),
b4592168
GD
5337 Parameter_Associations => Args));
5338 end if;
70482933 5339
048e5cef 5340 if Needs_Finalization (T) then
70482933 5341
df3e68b1
HK
5342 -- Generate:
5343 -- [Deep_]Initialize (Init_Arg1);
70482933 5344
2168d7cc 5345 Init_Call :=
243cae0a
AC
5346 Make_Init_Call
5347 (Obj_Ref => New_Copy_Tree (Init_Arg1),
2168d7cc
AC
5348 Typ => T);
5349
5350 -- Guard against a missing [Deep_]Initialize when the
5351 -- designated type was not properly frozen.
5352
5353 if Present (Init_Call) then
5354 Insert_Action (N, Init_Call);
5355 end if;
70482933
RK
5356 end if;
5357
e4494292 5358 Rewrite (N, New_Occurrence_Of (Temp, Loc));
b4592168 5359 Analyze_And_Resolve (N, PtrT);
f7937111
GD
5360
5361 -- When designated type has Default_Initial_Condition aspects,
5362 -- make a call to the type's DIC procedure to perform the
5363 -- checks. Theoretically this might also be needed for cases
5364 -- where the type doesn't have an init proc, but those should
5365 -- be very uncommon, and for now we only support the init proc
5366 -- case. ???
5367
5368 if Has_DIC (Dtyp)
5369 and then Present (DIC_Procedure (Dtyp))
5370 and then not Has_Null_Body (DIC_Procedure (Dtyp))
5371 then
5372 Insert_Action (N,
5373 Build_DIC_Call (Loc,
5374 Make_Explicit_Dereference (Loc,
5375 Prefix => New_Occurrence_Of (Temp, Loc)),
5376 Dtyp));
5377 end if;
b4592168 5378 end if;
26bff3d9
JM
5379 end if;
5380 end;
f82944b7 5381
26bff3d9
JM
5382 -- Ada 2005 (AI-251): If the allocator is for a class-wide interface
5383 -- object that has been rewritten as a reference, we displace "this"
5384 -- to reference properly its secondary dispatch table.
5385
533369aa 5386 if Nkind (N) = N_Identifier and then Is_Interface (Dtyp) then
26bff3d9 5387 Displace_Allocator_Pointer (N);
f82944b7
JM
5388 end if;
5389
fbf5a39b
AC
5390 exception
5391 when RE_Not_Available =>
5392 return;
70482933
RK
5393 end Expand_N_Allocator;
5394
5395 -----------------------
5396 -- Expand_N_And_Then --
5397 -----------------------
5398
5875f8d6
AC
5399 procedure Expand_N_And_Then (N : Node_Id)
5400 renames Expand_Short_Circuit_Operator;
70482933 5401
19d846a0
RD
5402 ------------------------------
5403 -- Expand_N_Case_Expression --
5404 ------------------------------
5405
5406 procedure Expand_N_Case_Expression (N : Node_Id) is
e44e8a5e
AC
5407 function Is_Copy_Type (Typ : Entity_Id) return Boolean;
5408 -- Return True if we can copy objects of this type when expanding a case
5409 -- expression.
5410
5411 ------------------
5412 -- Is_Copy_Type --
5413 ------------------
5414
5415 function Is_Copy_Type (Typ : Entity_Id) return Boolean is
5416 begin
e0666fc6 5417 -- If Minimize_Expression_With_Actions is True, we can afford to copy
e44e8a5e
AC
5418 -- large objects, as long as they are constrained and not limited.
5419
5420 return
5421 Is_Elementary_Type (Underlying_Type (Typ))
5422 or else
5423 (Minimize_Expression_With_Actions
5424 and then Is_Constrained (Underlying_Type (Typ))
5b4ce2a0 5425 and then not Is_Limited_Type (Underlying_Type (Typ)));
e44e8a5e
AC
5426 end Is_Copy_Type;
5427
5428 -- Local variables
5429
5430 Loc : constant Source_Ptr := Sloc (N);
5431 Par : constant Node_Id := Parent (N);
5432 Typ : constant Entity_Id := Etype (N);
5433
0da343bc
AC
5434 Acts : List_Id;
5435 Alt : Node_Id;
5436 Case_Stmt : Node_Id;
5437 Decl : Node_Id;
5438 Expr : Node_Id;
773e99ac 5439 Target : Entity_Id := Empty;
0da343bc
AC
5440 Target_Typ : Entity_Id;
5441
5442 In_Predicate : Boolean := False;
5443 -- Flag set when the case expression appears within a predicate
5444
be035558 5445 Optimize_Return_Stmt : Boolean := False;
0da343bc
AC
5446 -- Flag set when the case expression can be optimized in the context of
5447 -- a simple return statement.
19d846a0 5448
e44e8a5e
AC
5449 -- Start of processing for Expand_N_Case_Expression
5450
19d846a0 5451 begin
b6b5cca8
AC
5452 -- Check for MINIMIZED/ELIMINATED overflow mode
5453
5454 if Minimized_Eliminated_Overflow_Check (N) then
4b1c4f20
RD
5455 Apply_Arithmetic_Overflow_Check (N);
5456 return;
5457 end if;
5458
21d7ef70
AC
5459 -- If the case expression is a predicate specification, and the type
5460 -- to which it applies has a static predicate aspect, do not expand,
5461 -- because it will be converted to the proper predicate form later.
ff1f1705 5462
4a08c95c 5463 if Ekind (Current_Scope) in E_Function | E_Procedure
ff1f1705
AC
5464 and then Is_Predicate_Function (Current_Scope)
5465 then
be035558
AC
5466 In_Predicate := True;
5467
5468 if Has_Static_Predicate_Aspect (Etype (First_Entity (Current_Scope)))
5469 then
5470 return;
5471 end if;
ff1f1705
AC
5472 end if;
5473
0da343bc 5474 -- When the type of the case expression is elementary, expand
19d846a0 5475
0da343bc 5476 -- (case X is when A => AX, when B => BX ...)
19d846a0 5477
0da343bc 5478 -- into
19d846a0
RD
5479
5480 -- do
0da343bc 5481 -- Target : Typ;
19d846a0
RD
5482 -- case X is
5483 -- when A =>
be035558 5484 -- Target := AX;
19d846a0 5485 -- when B =>
be035558 5486 -- Target := BX;
19d846a0
RD
5487 -- ...
5488 -- end case;
be035558
AC
5489 -- in Target end;
5490
0da343bc 5491 -- In all other cases expand into
19d846a0
RD
5492
5493 -- do
0da343bc 5494 -- type Ptr_Typ is access all Typ;
be035558 5495 -- Target : Ptr_Typ;
19d846a0
RD
5496 -- case X is
5497 -- when A =>
be035558 5498 -- Target := AX'Unrestricted_Access;
19d846a0 5499 -- when B =>
be035558 5500 -- Target := BX'Unrestricted_Access;
19d846a0
RD
5501 -- ...
5502 -- end case;
be035558 5503 -- in Target.all end;
19d846a0 5504
0da343bc
AC
5505 -- This approach avoids extra copies of potentially large objects. It
5506 -- also allows handling of values of limited or unconstrained types.
e0666fc6 5507 -- Note that we do the copy also for constrained, nonlimited types
e44e8a5e
AC
5508 -- when minimizing expressions with actions (e.g. when generating C
5509 -- code) since it allows us to do the optimization below in more cases.
0da343bc
AC
5510
5511 -- Small optimization: when the case expression appears in the context
5512 -- of a simple return statement, expand into
5513
5514 -- case X is
5515 -- when A =>
5516 -- return AX;
5517 -- when B =>
5518 -- return BX;
5519 -- ...
5520 -- end case;
5521
be035558 5522 Case_Stmt :=
19d846a0
RD
5523 Make_Case_Statement (Loc,
5524 Expression => Expression (N),
5525 Alternatives => New_List);
5526
414c6563
AC
5527 -- Preserve the original context for which the case statement is being
5528 -- generated. This is needed by the finalization machinery to prevent
5529 -- the premature finalization of controlled objects found within the
5530 -- case statement.
5531
be035558
AC
5532 Set_From_Conditional_Expression (Case_Stmt);
5533 Acts := New_List;
19d846a0 5534
e44e8a5e 5535 -- Scalar/Copy case
19d846a0 5536
e44e8a5e 5537 if Is_Copy_Type (Typ) then
be035558
AC
5538 Target_Typ := Typ;
5539
0964be07
BD
5540 -- Do not perform the optimization when the return statement is
5541 -- within a predicate function, as this causes spurious errors.
be035558 5542
0da343bc
AC
5543 Optimize_Return_Stmt :=
5544 Nkind (Par) = N_Simple_Return_Statement and then not In_Predicate;
5545
5546 -- Otherwise create an access type to handle the general case using
5547 -- 'Unrestricted_Access.
5548
5549 -- Generate:
5550 -- type Ptr_Typ is access all Typ;
19d846a0
RD
5551
5552 else
211e7410
AC
5553 if Generate_C_Code then
5554
0c3ef0cc
GD
5555 -- We cannot ensure that correct C code will be generated if any
5556 -- temporary is created down the line (to e.g. handle checks or
5557 -- capture values) since we might end up with dangling references
5558 -- to local variables, so better be safe and reject the construct.
211e7410
AC
5559
5560 Error_Msg_N
5561 ("case expression too complex, use case statement instead", N);
5562 end if;
5563
0da343bc
AC
5564 Target_Typ := Make_Temporary (Loc, 'P');
5565
be035558 5566 Append_To (Acts,
19d846a0 5567 Make_Full_Type_Declaration (Loc,
0da343bc 5568 Defining_Identifier => Target_Typ,
11d59a86 5569 Type_Definition =>
19d846a0 5570 Make_Access_To_Object_Definition (Loc,
11d59a86 5571 All_Present => True,
e4494292 5572 Subtype_Indication => New_Occurrence_Of (Typ, Loc))));
19d846a0
RD
5573 end if;
5574
0da343bc
AC
5575 -- Create the declaration of the target which captures the value of the
5576 -- expression.
5577
5578 -- Generate:
5579 -- Target : [Ptr_]Typ;
5580
be035558
AC
5581 if not Optimize_Return_Stmt then
5582 Target := Make_Temporary (Loc, 'T');
27a8f150 5583
be035558
AC
5584 Decl :=
5585 Make_Object_Declaration (Loc,
5586 Defining_Identifier => Target,
5587 Object_Definition => New_Occurrence_Of (Target_Typ, Loc));
5588 Set_No_Initialization (Decl);
0da343bc 5589
be035558
AC
5590 Append_To (Acts, Decl);
5591 end if;
19d846a0 5592
0da343bc 5593 -- Process the alternatives
19d846a0
RD
5594
5595 Alt := First (Alternatives (N));
5596 while Present (Alt) loop
5597 declare
be035558
AC
5598 Alt_Expr : Node_Id := Expression (Alt);
5599 Alt_Loc : constant Source_Ptr := Sloc (Alt_Expr);
5b4ce2a0 5600 LHS : Node_Id;
be035558 5601 Stmts : List_Id;
19d846a0
RD
5602
5603 begin
0da343bc
AC
5604 -- Take the unrestricted access of the expression value for non-
5605 -- scalar types. This approach avoids big copies and covers the
5606 -- limited and unconstrained cases.
5607
5608 -- Generate:
5609 -- AX'Unrestricted_Access
05dbd302 5610
e44e8a5e 5611 if not Is_Copy_Type (Typ) then
be035558
AC
5612 Alt_Expr :=
5613 Make_Attribute_Reference (Alt_Loc,
5614 Prefix => Relocate_Node (Alt_Expr),
19d846a0
RD
5615 Attribute_Name => Name_Unrestricted_Access);
5616 end if;
5617
0da343bc
AC
5618 -- Generate:
5619 -- return AX['Unrestricted_Access];
5620
be035558
AC
5621 if Optimize_Return_Stmt then
5622 Stmts := New_List (
5623 Make_Simple_Return_Statement (Alt_Loc,
5624 Expression => Alt_Expr));
0da343bc
AC
5625
5626 -- Generate:
5627 -- Target := AX['Unrestricted_Access];
5628
be035558 5629 else
5b4ce2a0
HK
5630 LHS := New_Occurrence_Of (Target, Loc);
5631 Set_Assignment_OK (LHS);
5632
be035558
AC
5633 Stmts := New_List (
5634 Make_Assignment_Statement (Alt_Loc,
5b4ce2a0 5635 Name => LHS,
be035558
AC
5636 Expression => Alt_Expr));
5637 end if;
eaed0c37
AC
5638
5639 -- Propagate declarations inserted in the node by Insert_Actions
5640 -- (for example, temporaries generated to remove side effects).
5641 -- These actions must remain attached to the alternative, given
5642 -- that they are generated by the corresponding expression.
5643
be035558
AC
5644 if Present (Actions (Alt)) then
5645 Prepend_List (Actions (Alt), Stmts);
eaed0c37
AC
5646 end if;
5647
937e9676
AC
5648 -- Finalize any transient objects on exit from the alternative.
5649 -- This is done only in the return optimization case because
5650 -- otherwise the case expression is converted into an expression
5651 -- with actions which already contains this form of processing.
0da343bc
AC
5652
5653 if Optimize_Return_Stmt then
5654 Process_If_Case_Statements (N, Stmts);
5655 end if;
5656
19d846a0 5657 Append_To
be035558 5658 (Alternatives (Case_Stmt),
19d846a0
RD
5659 Make_Case_Statement_Alternative (Sloc (Alt),
5660 Discrete_Choices => Discrete_Choices (Alt),
be035558 5661 Statements => Stmts));
19d846a0
RD
5662 end;
5663
5664 Next (Alt);
5665 end loop;
5666
0da343bc 5667 -- Rewrite the parent return statement as a case statement
be035558
AC
5668
5669 if Optimize_Return_Stmt then
be035558
AC
5670 Rewrite (Par, Case_Stmt);
5671 Analyze (Par);
be035558 5672
0da343bc 5673 -- Otherwise convert the case expression into an expression with actions
19d846a0 5674
19d846a0 5675 else
0da343bc 5676 Append_To (Acts, Case_Stmt);
19d846a0 5677
e44e8a5e 5678 if Is_Copy_Type (Typ) then
0da343bc 5679 Expr := New_Occurrence_Of (Target, Loc);
19d846a0 5680
0da343bc
AC
5681 else
5682 Expr :=
5683 Make_Explicit_Dereference (Loc,
5684 Prefix => New_Occurrence_Of (Target, Loc));
5685 end if;
5686
5687 -- Generate:
5688 -- do
5689 -- ...
5690 -- in Target[.all] end;
5691
5692 Rewrite (N,
5693 Make_Expression_With_Actions (Loc,
5694 Expression => Expr,
5695 Actions => Acts));
5696
5697 Analyze_And_Resolve (N, Typ);
5698 end if;
19d846a0
RD
5699 end Expand_N_Case_Expression;
5700
9b16cb57
RD
5701 -----------------------------------
5702 -- Expand_N_Explicit_Dereference --
5703 -----------------------------------
5704
5705 procedure Expand_N_Explicit_Dereference (N : Node_Id) is
5706 begin
5707 -- Insert explicit dereference call for the checked storage pool case
5708
5709 Insert_Dereference_Action (Prefix (N));
5710
5711 -- If the type is an Atomic type for which Atomic_Sync is enabled, then
5712 -- we set the atomic sync flag.
5713
5714 if Is_Atomic (Etype (N))
5715 and then not Atomic_Synchronization_Disabled (Etype (N))
5716 then
5717 Activate_Atomic_Synchronization (N);
5718 end if;
5719 end Expand_N_Explicit_Dereference;
5720
5721 --------------------------------------
5722 -- Expand_N_Expression_With_Actions --
5723 --------------------------------------
5724
5725 procedure Expand_N_Expression_With_Actions (N : Node_Id) is
e3d9f448
AC
5726 Acts : constant List_Id := Actions (N);
5727
5728 procedure Force_Boolean_Evaluation (Expr : Node_Id);
5729 -- Force the evaluation of Boolean expression Expr
5730
4c7e0990 5731 function Process_Action (Act : Node_Id) return Traverse_Result;
b2c28399 5732 -- Inspect and process a single action of an expression_with_actions for
937e9676
AC
5733 -- transient objects. If such objects are found, the routine generates
5734 -- code to clean them up when the context of the expression is evaluated
5735 -- or elaborated.
9b16cb57 5736
e3d9f448
AC
5737 ------------------------------
5738 -- Force_Boolean_Evaluation --
5739 ------------------------------
5740
5741 procedure Force_Boolean_Evaluation (Expr : Node_Id) is
5742 Loc : constant Source_Ptr := Sloc (N);
5743 Flag_Decl : Node_Id;
5744 Flag_Id : Entity_Id;
5745
5746 begin
5747 -- Relocate the expression to the actions list by capturing its value
5748 -- in a Boolean flag. Generate:
5749 -- Flag : constant Boolean := Expr;
5750
5751 Flag_Id := Make_Temporary (Loc, 'F');
5752
5753 Flag_Decl :=
5754 Make_Object_Declaration (Loc,
5755 Defining_Identifier => Flag_Id,
5756 Constant_Present => True,
5757 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
5758 Expression => Relocate_Node (Expr));
5759
5760 Append (Flag_Decl, Acts);
5761 Analyze (Flag_Decl);
5762
5763 -- Replace the expression with a reference to the flag
5764
5765 Rewrite (Expression (N), New_Occurrence_Of (Flag_Id, Loc));
5766 Analyze (Expression (N));
5767 end Force_Boolean_Evaluation;
5768
4c7e0990
AC
5769 --------------------
5770 -- Process_Action --
5771 --------------------
5772
5773 function Process_Action (Act : Node_Id) return Traverse_Result is
4c7e0990
AC
5774 begin
5775 if Nkind (Act) = N_Object_Declaration
5776 and then Is_Finalizable_Transient (Act, N)
5777 then
937e9676 5778 Process_Transient_In_Expression (Act, N, Acts);
05344a33 5779 return Skip;
9b16cb57 5780
4c7e0990
AC
5781 -- Avoid processing temporary function results multiple times when
5782 -- dealing with nested expression_with_actions.
9b16cb57 5783
4c7e0990
AC
5784 elsif Nkind (Act) = N_Expression_With_Actions then
5785 return Abandon;
5786
b2c28399
AC
5787 -- Do not process temporary function results in loops. This is done
5788 -- by Expand_N_Loop_Statement and Build_Finalizer.
4c7e0990
AC
5789
5790 elsif Nkind (Act) = N_Loop_Statement then
5791 return Abandon;
9b16cb57
RD
5792 end if;
5793
4c7e0990
AC
5794 return OK;
5795 end Process_Action;
9b16cb57 5796
4c7e0990 5797 procedure Process_Single_Action is new Traverse_Proc (Process_Action);
9b16cb57
RD
5798
5799 -- Local variables
5800
e3d9f448 5801 Act : Node_Id;
9b16cb57
RD
5802
5803 -- Start of processing for Expand_N_Expression_With_Actions
5804
5805 begin
4b17187f
AC
5806 -- Do not evaluate the expression when it denotes an entity because the
5807 -- expression_with_actions node will be replaced by the reference.
5808
e3d9f448 5809 if Is_Entity_Name (Expression (N)) then
4b17187f
AC
5810 null;
5811
5812 -- Do not evaluate the expression when there are no actions because the
5813 -- expression_with_actions node will be replaced by the expression.
5814
5815 elsif No (Acts) or else Is_Empty_List (Acts) then
5816 null;
5817
5818 -- Force the evaluation of the expression by capturing its value in a
937e9676
AC
5819 -- temporary. This ensures that aliases of transient objects do not leak
5820 -- to the expression of the expression_with_actions node:
4b17187f
AC
5821
5822 -- do
7782ff67 5823 -- Trans_Id : Ctrl_Typ := ...;
4b17187f
AC
5824 -- Alias : ... := Trans_Id;
5825 -- in ... Alias ... end;
5826
5827 -- In the example above, Trans_Id cannot be finalized at the end of the
5828 -- actions list because this may affect the alias and the final value of
5829 -- the expression_with_actions. Forcing the evaluation encapsulates the
5830 -- reference to the Alias within the actions list:
5831
5832 -- do
7782ff67 5833 -- Trans_Id : Ctrl_Typ := ...;
4b17187f
AC
5834 -- Alias : ... := Trans_Id;
5835 -- Val : constant Boolean := ... Alias ...;
5836 -- <finalize Trans_Id>
5837 -- in Val end;
e0f63680 5838
e3d9f448 5839 -- Once this transformation is performed, it is safe to finalize the
937e9676 5840 -- transient object at the end of the actions list.
e3d9f448
AC
5841
5842 -- Note that Force_Evaluation does not remove side effects in operators
5843 -- because it assumes that all operands are evaluated and side effect
5844 -- free. This is not the case when an operand depends implicitly on the
937e9676 5845 -- transient object through the use of access types.
e3d9f448
AC
5846
5847 elsif Is_Boolean_Type (Etype (Expression (N))) then
5848 Force_Boolean_Evaluation (Expression (N));
5849
6031f544 5850 -- The expression of an expression_with_actions node may not necessarily
e3d9f448
AC
5851 -- be Boolean when the node appears in an if expression. In this case do
5852 -- the usual forced evaluation to encapsulate potential aliasing.
4b17187f
AC
5853
5854 else
e3d9f448 5855 Force_Evaluation (Expression (N));
4b17187f
AC
5856 end if;
5857
937e9676
AC
5858 -- Process all transient objects found within the actions of the EWA
5859 -- node.
4b17187f
AC
5860
5861 Act := First (Acts);
e0f63680
AC
5862 while Present (Act) loop
5863 Process_Single_Action (Act);
5864 Next (Act);
5865 end loop;
5866
ebdaa81b 5867 -- Deal with case where there are no actions. In this case we simply
5a521b8a 5868 -- rewrite the node with its expression since we don't need the actions
ebdaa81b
AC
5869 -- and the specification of this node does not allow a null action list.
5870
5a521b8a
AC
5871 -- Note: we use Rewrite instead of Replace, because Codepeer is using
5872 -- the expanded tree and relying on being able to retrieve the original
5873 -- tree in cases like this. This raises a whole lot of issues of whether
5874 -- we have problems elsewhere, which will be addressed in the future???
5875
4b17187f 5876 if Is_Empty_List (Acts) then
5a521b8a 5877 Rewrite (N, Relocate_Node (Expression (N)));
ebdaa81b 5878 end if;
9b16cb57
RD
5879 end Expand_N_Expression_With_Actions;
5880
5881 ----------------------------
5882 -- Expand_N_If_Expression --
5883 ----------------------------
70482933 5884
4b985e20 5885 -- Deal with limited types and condition actions
70482933 5886
9b16cb57 5887 procedure Expand_N_If_Expression (N : Node_Id) is
0da343bc
AC
5888 Cond : constant Node_Id := First (Expressions (N));
5889 Loc : constant Source_Ptr := Sloc (N);
5890 Thenx : constant Node_Id := Next (Cond);
5891 Elsex : constant Node_Id := Next (Thenx);
5892 Typ : constant Entity_Id := Etype (N);
c471e2da 5893
773e99ac
JS
5894 Actions : List_Id;
5895 Decl : Node_Id;
5896 Expr : Node_Id;
5897 New_If : Node_Id;
5898 New_N : Node_Id;
5899
5900 -- Determine if we are dealing with a special case of a conditional
5901 -- expression used as an actual for an anonymous access type which
5902 -- forces us to transform the if expression into an expression with
5903 -- actions in order to create a temporary to capture the level of the
5904 -- expression in each branch.
5905
5906 Force_Expand : constant Boolean := Is_Anonymous_Access_Actual (N);
5907
5908 -- Start of processing for Expand_N_If_Expression
70482933
RK
5909
5910 begin
369965ea
AC
5911 -- Check for MINIMIZED/ELIMINATED overflow mode.
5912 -- Apply_Arithmetic_Overflow_Check will not deal with Then/Else_Actions
5913 -- so skip this step if any actions are present.
b6b5cca8 5914
369965ea
AC
5915 if Minimized_Eliminated_Overflow_Check (N)
5916 and then No (Then_Actions (N))
5917 and then No (Else_Actions (N))
5918 then
b6b5cca8
AC
5919 Apply_Arithmetic_Overflow_Check (N);
5920 return;
5921 end if;
5922
602a7ec0 5923 -- Fold at compile time if condition known. We have already folded
9b16cb57
RD
5924 -- static if expressions, but it is possible to fold any case in which
5925 -- the condition is known at compile time, even though the result is
5926 -- non-static.
602a7ec0
AC
5927
5928 -- Note that we don't do the fold of such cases in Sem_Elab because
5929 -- it can cause infinite loops with the expander adding a conditional
5930 -- expression, and Sem_Elab circuitry removing it repeatedly.
5931
5932 if Compile_Time_Known_Value (Cond) then
f916243b
AC
5933 declare
5934 function Fold_Known_Value (Cond : Node_Id) return Boolean;
0da343bc
AC
5935 -- Fold at compile time. Assumes condition known. Return True if
5936 -- folding occurred, meaning we're done.
602a7ec0 5937
f916243b
AC
5938 ----------------------
5939 -- Fold_Known_Value --
5940 ----------------------
ae77c68b 5941
f916243b
AC
5942 function Fold_Known_Value (Cond : Node_Id) return Boolean is
5943 begin
5944 if Is_True (Expr_Value (Cond)) then
5945 Expr := Thenx;
5946 Actions := Then_Actions (N);
5947 else
5948 Expr := Elsex;
5949 Actions := Else_Actions (N);
5950 end if;
602a7ec0 5951
f916243b 5952 Remove (Expr);
602a7ec0 5953
f916243b
AC
5954 if Present (Actions) then
5955
7548f2cb
AC
5956 -- To minimize the use of Expression_With_Actions, just skip
5957 -- the optimization as it is not critical for correctness.
f916243b
AC
5958
5959 if Minimize_Expression_With_Actions then
5960 return False;
5961 end if;
5962
5963 Rewrite (N,
5964 Make_Expression_With_Actions (Loc,
5965 Expression => Relocate_Node (Expr),
5966 Actions => Actions));
5967 Analyze_And_Resolve (N, Typ);
5968
5969 else
5970 Rewrite (N, Relocate_Node (Expr));
5971 end if;
5972
5973 -- Note that the result is never static (legitimate cases of
5974 -- static if expressions were folded in Sem_Eval).
5975
5976 Set_Is_Static_Expression (N, False);
5977 return True;
5978 end Fold_Known_Value;
5979
5980 begin
5981 if Fold_Known_Value (Cond) then
5982 return;
5983 end if;
5984 end;
602a7ec0
AC
5985 end if;
5986
113a9fb6
AC
5987 -- If the type is limited, and the back end does not handle limited
5988 -- types, then we expand as follows to avoid the possibility of
5989 -- improper copying.
ac7120ce 5990
c471e2da
AC
5991 -- type Ptr is access all Typ;
5992 -- Cnn : Ptr;
ac7120ce
RD
5993 -- if cond then
5994 -- <<then actions>>
5995 -- Cnn := then-expr'Unrestricted_Access;
5996 -- else
5997 -- <<else actions>>
5998 -- Cnn := else-expr'Unrestricted_Access;
5999 -- end if;
6000
9b16cb57 6001 -- and replace the if expression by a reference to Cnn.all.
ac7120ce 6002
305caf42
AC
6003 -- This special case can be skipped if the back end handles limited
6004 -- types properly and ensures that no incorrect copies are made.
6005
6006 if Is_By_Reference_Type (Typ)
6007 and then not Back_End_Handles_Limited_Types
6008 then
b2c28399
AC
6009 -- When the "then" or "else" expressions involve controlled function
6010 -- calls, generated temporaries are chained on the corresponding list
6011 -- of actions. These temporaries need to be finalized after the if
6012 -- expression is evaluated.
3cebd1c0 6013
0da343bc
AC
6014 Process_If_Case_Statements (N, Then_Actions (N));
6015 Process_If_Case_Statements (N, Else_Actions (N));
3cebd1c0 6016
3fc40cd7
PMR
6017 declare
6018 Cnn : constant Entity_Id := Make_Temporary (Loc, 'C', N);
6019 Ptr_Typ : constant Entity_Id := Make_Temporary (Loc, 'A');
e201023c 6020
3fc40cd7
PMR
6021 begin
6022 -- Generate:
6023 -- type Ann is access all Typ;
3cebd1c0 6024
3fc40cd7
PMR
6025 Insert_Action (N,
6026 Make_Full_Type_Declaration (Loc,
6027 Defining_Identifier => Ptr_Typ,
6028 Type_Definition =>
6029 Make_Access_To_Object_Definition (Loc,
6030 All_Present => True,
6031 Subtype_Indication => New_Occurrence_Of (Typ, Loc))));
3cebd1c0 6032
3fc40cd7
PMR
6033 -- Generate:
6034 -- Cnn : Ann;
3cebd1c0 6035
3fc40cd7
PMR
6036 Decl :=
6037 Make_Object_Declaration (Loc,
6038 Defining_Identifier => Cnn,
6039 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc));
3cebd1c0 6040
3fc40cd7
PMR
6041 -- Generate:
6042 -- if Cond then
6043 -- Cnn := <Thenx>'Unrestricted_Access;
6044 -- else
6045 -- Cnn := <Elsex>'Unrestricted_Access;
6046 -- end if;
3cebd1c0 6047
3fc40cd7
PMR
6048 New_If :=
6049 Make_Implicit_If_Statement (N,
6050 Condition => Relocate_Node (Cond),
6051 Then_Statements => New_List (
6052 Make_Assignment_Statement (Sloc (Thenx),
6053 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
6054 Expression =>
6055 Make_Attribute_Reference (Loc,
6056 Prefix => Relocate_Node (Thenx),
6057 Attribute_Name => Name_Unrestricted_Access))),
3cebd1c0 6058
3fc40cd7
PMR
6059 Else_Statements => New_List (
6060 Make_Assignment_Statement (Sloc (Elsex),
6061 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
6062 Expression =>
6063 Make_Attribute_Reference (Loc,
6064 Prefix => Relocate_Node (Elsex),
6065 Attribute_Name => Name_Unrestricted_Access))));
6066
6067 -- Preserve the original context for which the if statement is
6068 -- being generated. This is needed by the finalization machinery
6069 -- to prevent the premature finalization of controlled objects
6070 -- found within the if statement.
6071
6072 Set_From_Conditional_Expression (New_If);
6073
6074 New_N :=
6075 Make_Explicit_Dereference (Loc,
6076 Prefix => New_Occurrence_Of (Cnn, Loc));
6077 end;
fb1949a0 6078
113a9fb6
AC
6079 -- If the result is an unconstrained array and the if expression is in a
6080 -- context other than the initializing expression of the declaration of
6081 -- an object, then we pull out the if expression as follows:
6082
6083 -- Cnn : constant typ := if-expression
6084
6085 -- and then replace the if expression with an occurrence of Cnn. This
6086 -- avoids the need in the back end to create on-the-fly variable length
6087 -- temporaries (which it cannot do!)
6088
6089 -- Note that the test for being in an object declaration avoids doing an
6090 -- unnecessary expansion, and also avoids infinite recursion.
6091
6092 elsif Is_Array_Type (Typ) and then not Is_Constrained (Typ)
6093 and then (Nkind (Parent (N)) /= N_Object_Declaration
6094 or else Expression (Parent (N)) /= N)
6095 then
6096 declare
6097 Cnn : constant Node_Id := Make_Temporary (Loc, 'C', N);
e201023c 6098
113a9fb6
AC
6099 begin
6100 Insert_Action (N,
6101 Make_Object_Declaration (Loc,
6102 Defining_Identifier => Cnn,
6103 Constant_Present => True,
6104 Object_Definition => New_Occurrence_Of (Typ, Loc),
6105 Expression => Relocate_Node (N),
6106 Has_Init_Expression => True));
6107
6108 Rewrite (N, New_Occurrence_Of (Cnn, Loc));
6109 return;
6110 end;
6111
c471e2da 6112 -- For other types, we only need to expand if there are other actions
773e99ac
JS
6113 -- associated with either branch or we need to force expansion to deal
6114 -- with if expressions used as an actual of an anonymous access type.
c471e2da 6115
773e99ac
JS
6116 elsif Present (Then_Actions (N))
6117 or else Present (Else_Actions (N))
6118 or else Force_Expand
6119 then
c471e2da 6120
0812b84e 6121 -- We now wrap the actions into the appropriate expression
fb1949a0 6122
9d4f9832
AC
6123 if Minimize_Expression_With_Actions
6124 and then (Is_Elementary_Type (Underlying_Type (Typ))
6125 or else Is_Constrained (Underlying_Type (Typ)))
6126 then
f916243b
AC
6127 -- If we can't use N_Expression_With_Actions nodes, then we insert
6128 -- the following sequence of actions (using Insert_Actions):
305caf42 6129
f916243b
AC
6130 -- Cnn : typ;
6131 -- if cond then
6132 -- <<then actions>>
6133 -- Cnn := then-expr;
6134 -- else
6135 -- <<else actions>>
6136 -- Cnn := else-expr
6137 -- end if;
b2c28399 6138
f916243b 6139 -- and replace the if expression by a reference to Cnn
305caf42 6140
3fc40cd7
PMR
6141 declare
6142 Cnn : constant Node_Id := Make_Temporary (Loc, 'C', N);
e201023c 6143
3fc40cd7
PMR
6144 begin
6145 Decl :=
6146 Make_Object_Declaration (Loc,
6147 Defining_Identifier => Cnn,
6148 Object_Definition => New_Occurrence_Of (Typ, Loc));
f916243b 6149
3fc40cd7
PMR
6150 New_If :=
6151 Make_Implicit_If_Statement (N,
6152 Condition => Relocate_Node (Cond),
f916243b 6153
3fc40cd7
PMR
6154 Then_Statements => New_List (
6155 Make_Assignment_Statement (Sloc (Thenx),
6156 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
6157 Expression => Relocate_Node (Thenx))),
f916243b 6158
3fc40cd7
PMR
6159 Else_Statements => New_List (
6160 Make_Assignment_Statement (Sloc (Elsex),
6161 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
6162 Expression => Relocate_Node (Elsex))));
f916243b 6163
3fc40cd7
PMR
6164 Set_Assignment_OK (Name (First (Then_Statements (New_If))));
6165 Set_Assignment_OK (Name (First (Else_Statements (New_If))));
f916243b 6166
3fc40cd7
PMR
6167 New_N := New_Occurrence_Of (Cnn, Loc);
6168 end;
f916243b
AC
6169
6170 -- Regular path using Expression_With_Actions
6171
6172 else
6173 if Present (Then_Actions (N)) then
6174 Rewrite (Thenx,
6175 Make_Expression_With_Actions (Sloc (Thenx),
6176 Actions => Then_Actions (N),
6177 Expression => Relocate_Node (Thenx)));
6178
6179 Set_Then_Actions (N, No_List);
6180 Analyze_And_Resolve (Thenx, Typ);
6181 end if;
6182
6183 if Present (Else_Actions (N)) then
6184 Rewrite (Elsex,
6185 Make_Expression_With_Actions (Sloc (Elsex),
6186 Actions => Else_Actions (N),
6187 Expression => Relocate_Node (Elsex)));
6188
6189 Set_Else_Actions (N, No_List);
6190 Analyze_And_Resolve (Elsex, Typ);
6191 end if;
6192
773e99ac
JS
6193 -- We must force expansion into an expression with actions when
6194 -- an if expression gets used directly as an actual for an
6195 -- anonymous access type.
6196
6197 if Force_Expand then
6198 declare
6199 Cnn : constant Entity_Id := Make_Temporary (Loc, 'C');
6200 Acts : List_Id;
6201 begin
6202 Acts := New_List;
6203
6204 -- Generate:
6205 -- Cnn : Ann;
6206
6207 Decl :=
6208 Make_Object_Declaration (Loc,
6209 Defining_Identifier => Cnn,
6210 Object_Definition => New_Occurrence_Of (Typ, Loc));
6211 Append_To (Acts, Decl);
6212
6213 Set_No_Initialization (Decl);
6214
6215 -- Generate:
6216 -- if Cond then
6217 -- Cnn := <Thenx>;
6218 -- else
6219 -- Cnn := <Elsex>;
6220 -- end if;
6221
6222 New_If :=
6223 Make_Implicit_If_Statement (N,
6224 Condition => Relocate_Node (Cond),
6225 Then_Statements => New_List (
6226 Make_Assignment_Statement (Sloc (Thenx),
6227 Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
6228 Expression => Relocate_Node (Thenx))),
6229
6230 Else_Statements => New_List (
6231 Make_Assignment_Statement (Sloc (Elsex),
6232 Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
6233 Expression => Relocate_Node (Elsex))));
6234 Append_To (Acts, New_If);
6235
6236 -- Generate:
6237 -- do
6238 -- ...
6239 -- in Cnn end;
6240
6241 Rewrite (N,
6242 Make_Expression_With_Actions (Loc,
6243 Expression => New_Occurrence_Of (Cnn, Loc),
6244 Actions => Acts));
6245 Analyze_And_Resolve (N, Typ);
6246 end;
6247 end if;
6248
f916243b
AC
6249 return;
6250 end if;
0812b84e 6251
b2c28399
AC
6252 -- If no actions then no expansion needed, gigi will handle it using the
6253 -- same approach as a C conditional expression.
305caf42
AC
6254
6255 else
c471e2da
AC
6256 return;
6257 end if;
6258
305caf42 6259 -- Fall through here for either the limited expansion, or the case of
e0666fc6 6260 -- inserting actions for nonlimited types. In both these cases, we must
305caf42 6261 -- move the SLOC of the parent If statement to the newly created one and
3fc5d116
RD
6262 -- change it to the SLOC of the expression which, after expansion, will
6263 -- correspond to what is being evaluated.
c471e2da 6264
533369aa 6265 if Present (Parent (N)) and then Nkind (Parent (N)) = N_If_Statement then
c471e2da
AC
6266 Set_Sloc (New_If, Sloc (Parent (N)));
6267 Set_Sloc (Parent (N), Loc);
6268 end if;
70482933 6269
3fc5d116
RD
6270 -- Make sure Then_Actions and Else_Actions are appropriately moved
6271 -- to the new if statement.
6272
c471e2da
AC
6273 if Present (Then_Actions (N)) then
6274 Insert_List_Before
6275 (First (Then_Statements (New_If)), Then_Actions (N));
70482933 6276 end if;
c471e2da
AC
6277
6278 if Present (Else_Actions (N)) then
6279 Insert_List_Before
6280 (First (Else_Statements (New_If)), Else_Actions (N));
6281 end if;
6282
6283 Insert_Action (N, Decl);
6284 Insert_Action (N, New_If);
6285 Rewrite (N, New_N);
6286 Analyze_And_Resolve (N, Typ);
9b16cb57 6287 end Expand_N_If_Expression;
35a1c212 6288
70482933
RK
6289 -----------------
6290 -- Expand_N_In --
6291 -----------------
6292
6293 procedure Expand_N_In (N : Node_Id) is
7324bf49 6294 Loc : constant Source_Ptr := Sloc (N);
4818e7b9 6295 Restyp : constant Entity_Id := Etype (N);
7324bf49
AC
6296 Lop : constant Node_Id := Left_Opnd (N);
6297 Rop : constant Node_Id := Right_Opnd (N);
6298 Static : constant Boolean := Is_OK_Static_Expression (N);
70482933 6299
630d30e9
RD
6300 procedure Substitute_Valid_Check;
6301 -- Replaces node N by Lop'Valid. This is done when we have an explicit
6302 -- test for the left operand being in range of its subtype.
6303
6304 ----------------------------
6305 -- Substitute_Valid_Check --
6306 ----------------------------
6307
6308 procedure Substitute_Valid_Check is
356ffab8
AC
6309 function Is_OK_Object_Reference (Nod : Node_Id) return Boolean;
6310 -- Determine whether arbitrary node Nod denotes a source object that
6311 -- may safely act as prefix of attribute 'Valid.
6312
6313 ----------------------------
6314 -- Is_OK_Object_Reference --
6315 ----------------------------
6316
6317 function Is_OK_Object_Reference (Nod : Node_Id) return Boolean is
6318 Obj_Ref : Node_Id;
6319
6320 begin
6321 -- Inspect the original operand
6322
6323 Obj_Ref := Original_Node (Nod);
6324
6325 -- The object reference must be a source construct, otherwise the
6326 -- codefix suggestion may refer to nonexistent code from a user
6327 -- perspective.
6328
6329 if Comes_From_Source (Obj_Ref) then
356ffab8 6330 loop
4a08c95c 6331 if Nkind (Obj_Ref) in
0964be07
BD
6332 N_Type_Conversion |
6333 N_Unchecked_Type_Conversion |
6334 N_Qualified_Expression
356ffab8
AC
6335 then
6336 Obj_Ref := Expression (Obj_Ref);
6337 else
6338 exit;
6339 end if;
6340 end loop;
6341
6342 return Is_Object_Reference (Obj_Ref);
6343 end if;
6344
6345 return False;
6346 end Is_OK_Object_Reference;
6347
6348 -- Start of processing for Substitute_Valid_Check
6349
630d30e9 6350 begin
c7532b2d
AC
6351 Rewrite (N,
6352 Make_Attribute_Reference (Loc,
6353 Prefix => Relocate_Node (Lop),
6354 Attribute_Name => Name_Valid));
630d30e9 6355
c7532b2d 6356 Analyze_And_Resolve (N, Restyp);
630d30e9 6357
356ffab8
AC
6358 -- Emit a warning when the left-hand operand of the membership test
6359 -- is a source object, otherwise the use of attribute 'Valid would be
6360 -- illegal. The warning is not given when overflow checking is either
6361 -- MINIMIZED or ELIMINATED, as the danger of optimization has been
6362 -- eliminated above.
acad3c0a 6363
356ffab8
AC
6364 if Is_OK_Object_Reference (Lop)
6365 and then Overflow_Check_Mode not in Minimized_Or_Eliminated
6366 then
324ac540
AC
6367 Error_Msg_N
6368 ("??explicit membership test may be optimized away", N);
acad3c0a 6369 Error_Msg_N -- CODEFIX
324ac540 6370 ("\??use ''Valid attribute instead", N);
acad3c0a 6371 end if;
630d30e9
RD
6372 end Substitute_Valid_Check;
6373
356ffab8
AC
6374 -- Local variables
6375
6376 Ltyp : Entity_Id;
6377 Rtyp : Entity_Id;
6378
630d30e9
RD
6379 -- Start of processing for Expand_N_In
6380
70482933 6381 begin
308e6f3a 6382 -- If set membership case, expand with separate procedure
4818e7b9 6383
197e4514 6384 if Present (Alternatives (N)) then
a3068ca6 6385 Expand_Set_Membership (N);
197e4514
AC
6386 return;
6387 end if;
6388
4818e7b9
RD
6389 -- Not set membership, proceed with expansion
6390
6391 Ltyp := Etype (Left_Opnd (N));
6392 Rtyp := Etype (Right_Opnd (N));
6393
5707e389 6394 -- If MINIMIZED/ELIMINATED overflow mode and type is a signed integer
f6194278
RD
6395 -- type, then expand with a separate procedure. Note the use of the
6396 -- flag No_Minimize_Eliminate to prevent infinite recursion.
6397
b55ef4b8 6398 if Minimized_Eliminated_Overflow_Check (Left_Opnd (N))
f6194278
RD
6399 and then not No_Minimize_Eliminate (N)
6400 then
6401 Expand_Membership_Minimize_Eliminate_Overflow (N);
6402 return;
6403 end if;
6404
630d30e9
RD
6405 -- Check case of explicit test for an expression in range of its
6406 -- subtype. This is suspicious usage and we replace it with a 'Valid
b6b5cca8 6407 -- test and give a warning for scalar types.
630d30e9 6408
4818e7b9 6409 if Is_Scalar_Type (Ltyp)
b6b5cca8
AC
6410
6411 -- Only relevant for source comparisons
6412
6413 and then Comes_From_Source (N)
6414
6415 -- In floating-point this is a standard way to check for finite values
6416 -- and using 'Valid would typically be a pessimization.
6417
4818e7b9 6418 and then not Is_Floating_Point_Type (Ltyp)
b6b5cca8
AC
6419
6420 -- Don't give the message unless right operand is a type entity and
6421 -- the type of the left operand matches this type. Note that this
6422 -- eliminates the cases where MINIMIZED/ELIMINATED mode overflow
6423 -- checks have changed the type of the left operand.
6424
630d30e9 6425 and then Nkind (Rop) in N_Has_Entity
4818e7b9 6426 and then Ltyp = Entity (Rop)
b6b5cca8 6427
b6b5cca8
AC
6428 -- Skip this for predicated types, where such expressions are a
6429 -- reasonable way of testing if something meets the predicate.
6430
3d6db7f8 6431 and then not Present (Predicate_Function (Ltyp))
630d30e9
RD
6432 then
6433 Substitute_Valid_Check;
6434 return;
6435 end if;
6436
20b5d666
JM
6437 -- Do validity check on operands
6438
6439 if Validity_Checks_On and Validity_Check_Operands then
6440 Ensure_Valid (Left_Opnd (N));
6441 Validity_Check_Range (Right_Opnd (N));
6442 end if;
6443
630d30e9 6444 -- Case of explicit range
fbf5a39b
AC
6445
6446 if Nkind (Rop) = N_Range then
6447 declare
630d30e9
RD
6448 Lo : constant Node_Id := Low_Bound (Rop);
6449 Hi : constant Node_Id := High_Bound (Rop);
6450
6451 Lo_Orig : constant Node_Id := Original_Node (Lo);
6452 Hi_Orig : constant Node_Id := Original_Node (Hi);
6453
c800f862
RD
6454 Lcheck : Compare_Result;
6455 Ucheck : Compare_Result;
fbf5a39b 6456
d766cee3
RD
6457 Warn1 : constant Boolean :=
6458 Constant_Condition_Warnings
c800f862
RD
6459 and then Comes_From_Source (N)
6460 and then not In_Instance;
d766cee3 6461 -- This must be true for any of the optimization warnings, we
9a0ddeee
AC
6462 -- clearly want to give them only for source with the flag on. We
6463 -- also skip these warnings in an instance since it may be the
6464 -- case that different instantiations have different ranges.
d766cee3
RD
6465
6466 Warn2 : constant Boolean :=
6467 Warn1
6468 and then Nkind (Original_Node (Rop)) = N_Range
6469 and then Is_Integer_Type (Etype (Lo));
6470 -- For the case where only one bound warning is elided, we also
6471 -- insist on an explicit range and an integer type. The reason is
6472 -- that the use of enumeration ranges including an end point is
9a0ddeee
AC
6473 -- common, as is the use of a subtype name, one of whose bounds is
6474 -- the same as the type of the expression.
d766cee3 6475
fbf5a39b 6476 begin
c95e0edc 6477 -- If test is explicit x'First .. x'Last, replace by valid check
630d30e9 6478
d766cee3 6479 if Is_Scalar_Type (Ltyp)
b6b5cca8
AC
6480
6481 -- And left operand is X'First where X matches left operand
6482 -- type (this eliminates cases of type mismatch, including
6483 -- the cases where ELIMINATED/MINIMIZED mode has changed the
6484 -- type of the left operand.
6485
630d30e9
RD
6486 and then Nkind (Lo_Orig) = N_Attribute_Reference
6487 and then Attribute_Name (Lo_Orig) = Name_First
6488 and then Nkind (Prefix (Lo_Orig)) in N_Has_Entity
d766cee3 6489 and then Entity (Prefix (Lo_Orig)) = Ltyp
b6b5cca8 6490
cc6f5d75 6491 -- Same tests for right operand
b6b5cca8 6492
630d30e9
RD
6493 and then Nkind (Hi_Orig) = N_Attribute_Reference
6494 and then Attribute_Name (Hi_Orig) = Name_Last
6495 and then Nkind (Prefix (Hi_Orig)) in N_Has_Entity
d766cee3 6496 and then Entity (Prefix (Hi_Orig)) = Ltyp
b6b5cca8
AC
6497
6498 -- Relevant only for source cases
6499
630d30e9
RD
6500 and then Comes_From_Source (N)
6501 then
6502 Substitute_Valid_Check;
4818e7b9 6503 goto Leave;
630d30e9
RD
6504 end if;
6505
d766cee3
RD
6506 -- If bounds of type are known at compile time, and the end points
6507 -- are known at compile time and identical, this is another case
6508 -- for substituting a valid test. We only do this for discrete
6509 -- types, since it won't arise in practice for float types.
6510
6511 if Comes_From_Source (N)
6512 and then Is_Discrete_Type (Ltyp)
6513 and then Compile_Time_Known_Value (Type_High_Bound (Ltyp))
6514 and then Compile_Time_Known_Value (Type_Low_Bound (Ltyp))
6515 and then Compile_Time_Known_Value (Lo)
6516 and then Compile_Time_Known_Value (Hi)
6517 and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
6518 and then Expr_Value (Type_Low_Bound (Ltyp)) = Expr_Value (Lo)
94eefd2e 6519
f6194278
RD
6520 -- Kill warnings in instances, since they may be cases where we
6521 -- have a test in the generic that makes sense with some types
6522 -- and not with other types.
94eefd2e 6523
5b85ad7d
PMR
6524 -- Similarly, do not rewrite membership as a validity check if
6525 -- within the predicate function for the type.
6526
ad277369
ES
6527 -- Finally, if the original bounds are type conversions, even
6528 -- if they have been folded into constants, there are different
6529 -- types involved and 'Valid is not appropriate.
6530
d766cee3 6531 then
5b85ad7d
PMR
6532 if In_Instance
6533 or else (Ekind (Current_Scope) = E_Function
6534 and then Is_Predicate_Function (Current_Scope))
6535 then
6536 null;
6537
ad277369
ES
6538 elsif Nkind (Lo_Orig) = N_Type_Conversion
6539 or else Nkind (Hi_Orig) = N_Type_Conversion
6540 then
6541 null;
6542
5b85ad7d
PMR
6543 else
6544 Substitute_Valid_Check;
6545 goto Leave;
6546 end if;
d766cee3
RD
6547 end if;
6548
9a0ddeee
AC
6549 -- If we have an explicit range, do a bit of optimization based on
6550 -- range analysis (we may be able to kill one or both checks).
630d30e9 6551
c800f862
RD
6552 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => False);
6553 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => False);
6554
630d30e9
RD
6555 -- If either check is known to fail, replace result by False since
6556 -- the other check does not matter. Preserve the static flag for
6557 -- legality checks, because we are constant-folding beyond RM 4.9.
fbf5a39b
AC
6558
6559 if Lcheck = LT or else Ucheck = GT then
c800f862 6560 if Warn1 then
685bc70f
AC
6561 Error_Msg_N ("?c?range test optimized away", N);
6562 Error_Msg_N ("\?c?value is known to be out of range", N);
d766cee3
RD
6563 end if;
6564
e4494292 6565 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
4818e7b9 6566 Analyze_And_Resolve (N, Restyp);
7324bf49 6567 Set_Is_Static_Expression (N, Static);
4818e7b9 6568 goto Leave;
fbf5a39b 6569
685094bf
RD
6570 -- If both checks are known to succeed, replace result by True,
6571 -- since we know we are in range.
fbf5a39b
AC
6572
6573 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
c800f862 6574 if Warn1 then
685bc70f
AC
6575 Error_Msg_N ("?c?range test optimized away", N);
6576 Error_Msg_N ("\?c?value is known to be in range", N);
d766cee3
RD
6577 end if;
6578
e4494292 6579 Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
4818e7b9 6580 Analyze_And_Resolve (N, Restyp);
7324bf49 6581 Set_Is_Static_Expression (N, Static);
4818e7b9 6582 goto Leave;
fbf5a39b 6583
d766cee3
RD
6584 -- If lower bound check succeeds and upper bound check is not
6585 -- known to succeed or fail, then replace the range check with
6586 -- a comparison against the upper bound.
fbf5a39b
AC
6587
6588 elsif Lcheck in Compare_GE then
94eefd2e 6589 if Warn2 and then not In_Instance then
324ac540
AC
6590 Error_Msg_N ("??lower bound test optimized away", Lo);
6591 Error_Msg_N ("\??value is known to be in range", Lo);
d766cee3
RD
6592 end if;
6593
fbf5a39b
AC
6594 Rewrite (N,
6595 Make_Op_Le (Loc,
6596 Left_Opnd => Lop,
6597 Right_Opnd => High_Bound (Rop)));
4818e7b9
RD
6598 Analyze_And_Resolve (N, Restyp);
6599 goto Leave;
fbf5a39b 6600
d766cee3
RD
6601 -- If upper bound check succeeds and lower bound check is not
6602 -- known to succeed or fail, then replace the range check with
6603 -- a comparison against the lower bound.
fbf5a39b
AC
6604
6605 elsif Ucheck in Compare_LE then
94eefd2e 6606 if Warn2 and then not In_Instance then
324ac540
AC
6607 Error_Msg_N ("??upper bound test optimized away", Hi);
6608 Error_Msg_N ("\??value is known to be in range", Hi);
d766cee3
RD
6609 end if;
6610
fbf5a39b
AC
6611 Rewrite (N,
6612 Make_Op_Ge (Loc,
6613 Left_Opnd => Lop,
6614 Right_Opnd => Low_Bound (Rop)));
4818e7b9
RD
6615 Analyze_And_Resolve (N, Restyp);
6616 goto Leave;
fbf5a39b 6617 end if;
c800f862
RD
6618
6619 -- We couldn't optimize away the range check, but there is one
6620 -- more issue. If we are checking constant conditionals, then we
6621 -- see if we can determine the outcome assuming everything is
6622 -- valid, and if so give an appropriate warning.
6623
6624 if Warn1 and then not Assume_No_Invalid_Values then
6625 Lcheck := Compile_Time_Compare (Lop, Lo, Assume_Valid => True);
6626 Ucheck := Compile_Time_Compare (Lop, Hi, Assume_Valid => True);
6627
6628 -- Result is out of range for valid value
6629
6630 if Lcheck = LT or else Ucheck = GT then
ed2233dc 6631 Error_Msg_N
685bc70f 6632 ("?c?value can only be in range if it is invalid", N);
c800f862
RD
6633
6634 -- Result is in range for valid value
6635
6636 elsif Lcheck in Compare_GE and then Ucheck in Compare_LE then
ed2233dc 6637 Error_Msg_N
685bc70f 6638 ("?c?value can only be out of range if it is invalid", N);
c800f862
RD
6639
6640 -- Lower bound check succeeds if value is valid
6641
6642 elsif Warn2 and then Lcheck in Compare_GE then
ed2233dc 6643 Error_Msg_N
685bc70f 6644 ("?c?lower bound check only fails if it is invalid", Lo);
c800f862
RD
6645
6646 -- Upper bound check succeeds if value is valid
6647
6648 elsif Warn2 and then Ucheck in Compare_LE then
ed2233dc 6649 Error_Msg_N
685bc70f 6650 ("?c?upper bound check only fails for invalid values", Hi);
c800f862
RD
6651 end if;
6652 end if;
fbf5a39b
AC
6653 end;
6654
6c8e4f7e
EB
6655 -- Try to narrow the operation
6656
6657 if Ltyp = Universal_Integer and then Nkind (N) = N_In then
6658 Narrow_Large_Operation (N);
6659 end if;
6660
fbf5a39b 6661 -- For all other cases of an explicit range, nothing to be done
70482933 6662
4818e7b9 6663 goto Leave;
70482933
RK
6664
6665 -- Here right operand is a subtype mark
6666
6667 else
6668 declare
11381028
AC
6669 Typ : Entity_Id := Etype (Rop);
6670 Is_Acc : constant Boolean := Is_Access_Type (Typ);
6671 Check_Null_Exclusion : Boolean;
6672 Cond : Node_Id := Empty;
6673 New_N : Node_Id;
6674 Obj : Node_Id := Lop;
6675 SCIL_Node : Node_Id;
70482933
RK
6676
6677 begin
6678 Remove_Side_Effects (Obj);
6679
6680 -- For tagged type, do tagged membership operation
6681
6682 if Is_Tagged_Type (Typ) then
fbf5a39b 6683
535a8637 6684 -- No expansion will be performed for VM targets, as the VM
c7a494c9 6685 -- back ends will handle the membership tests directly.
70482933 6686
1f110335 6687 if Tagged_Type_Expansion then
82878151
AC
6688 Tagged_Membership (N, SCIL_Node, New_N);
6689 Rewrite (N, New_N);
cc0b3bac 6690 Analyze_And_Resolve (N, Restyp, Suppress => All_Checks);
82878151
AC
6691
6692 -- Update decoration of relocated node referenced by the
6693 -- SCIL node.
6694
9a0ddeee 6695 if Generate_SCIL and then Present (SCIL_Node) then
7665e4bd 6696 Set_SCIL_Node (N, SCIL_Node);
82878151 6697 end if;
70482933
RK
6698 end if;
6699
4818e7b9 6700 goto Leave;
70482933 6701
c95e0edc 6702 -- If type is scalar type, rewrite as x in t'First .. t'Last.
70482933 6703 -- This reason we do this is that the bounds may have the wrong
c800f862
RD
6704 -- type if they come from the original type definition. Also this
6705 -- way we get all the processing above for an explicit range.
70482933 6706
f6194278 6707 -- Don't do this for predicated types, since in this case we
a90bd866 6708 -- want to check the predicate.
c0f136cd 6709
c7532b2d
AC
6710 elsif Is_Scalar_Type (Typ) then
6711 if No (Predicate_Function (Typ)) then
6712 Rewrite (Rop,
6713 Make_Range (Loc,
6714 Low_Bound =>
6715 Make_Attribute_Reference (Loc,
6716 Attribute_Name => Name_First,
e4494292 6717 Prefix => New_Occurrence_Of (Typ, Loc)),
c7532b2d
AC
6718
6719 High_Bound =>
6720 Make_Attribute_Reference (Loc,
6721 Attribute_Name => Name_Last,
e4494292 6722 Prefix => New_Occurrence_Of (Typ, Loc))));
c7532b2d
AC
6723 Analyze_And_Resolve (N, Restyp);
6724 end if;
70482933 6725
4818e7b9 6726 goto Leave;
5d09245e 6727
67a44a4c
EB
6728 -- Ada 2005 (AI95-0216 amended by AI12-0162): Program_Error is
6729 -- raised when evaluating an individual membership test if the
6730 -- subtype mark denotes a constrained Unchecked_Union subtype
6731 -- and the expression lacks inferable discriminants.
5d09245e
AC
6732
6733 elsif Is_Unchecked_Union (Base_Type (Typ))
6734 and then Is_Constrained (Typ)
6735 and then not Has_Inferable_Discriminants (Lop)
6736 then
67a44a4c
EB
6737 Rewrite (N,
6738 Make_Expression_With_Actions (Loc,
6739 Actions =>
6740 New_List (Make_Raise_Program_Error (Loc,
6741 Reason => PE_Unchecked_Union_Restriction)),
6742 Expression =>
6743 New_Occurrence_Of (Standard_False, Loc)));
6744 Analyze_And_Resolve (N, Restyp);
5d09245e 6745
4818e7b9 6746 goto Leave;
70482933
RK
6747 end if;
6748
fbf5a39b
AC
6749 -- Here we have a non-scalar type
6750
70482933 6751 if Is_Acc then
11381028
AC
6752
6753 -- If the null exclusion checks are not compatible, need to
6754 -- perform further checks. In other words, we cannot have
6755 -- Ltyp including null and Typ excluding null. All other cases
6756 -- are OK.
6757
6758 Check_Null_Exclusion :=
6759 Can_Never_Be_Null (Typ) and then not Can_Never_Be_Null (Ltyp);
70482933
RK
6760 Typ := Designated_Type (Typ);
6761 end if;
6762
6763 if not Is_Constrained (Typ) then
11381028 6764 Cond := New_Occurrence_Of (Standard_True, Loc);
70482933 6765
685094bf
RD
6766 -- For the constrained array case, we have to check the subscripts
6767 -- for an exact match if the lengths are non-zero (the lengths
6768 -- must match in any case).
70482933
RK
6769
6770 elsif Is_Array_Type (Typ) then
fbf5a39b 6771 Check_Subscripts : declare
9a0ddeee 6772 function Build_Attribute_Reference
2e071734
AC
6773 (E : Node_Id;
6774 Nam : Name_Id;
6775 Dim : Nat) return Node_Id;
9a0ddeee 6776 -- Build attribute reference E'Nam (Dim)
70482933 6777
9a0ddeee
AC
6778 -------------------------------
6779 -- Build_Attribute_Reference --
6780 -------------------------------
fbf5a39b 6781
9a0ddeee 6782 function Build_Attribute_Reference
2e071734
AC
6783 (E : Node_Id;
6784 Nam : Name_Id;
6785 Dim : Nat) return Node_Id
70482933
RK
6786 is
6787 begin
6788 return
6789 Make_Attribute_Reference (Loc,
9a0ddeee 6790 Prefix => E,
70482933 6791 Attribute_Name => Nam,
9a0ddeee 6792 Expressions => New_List (
70482933 6793 Make_Integer_Literal (Loc, Dim)));
9a0ddeee 6794 end Build_Attribute_Reference;
70482933 6795
fad0600d 6796 -- Start of processing for Check_Subscripts
fbf5a39b 6797
70482933
RK
6798 begin
6799 for J in 1 .. Number_Dimensions (Typ) loop
6800 Evolve_And_Then (Cond,
6801 Make_Op_Eq (Loc,
6802 Left_Opnd =>
9a0ddeee 6803 Build_Attribute_Reference
fbf5a39b
AC
6804 (Duplicate_Subexpr_No_Checks (Obj),
6805 Name_First, J),
70482933 6806 Right_Opnd =>
9a0ddeee 6807 Build_Attribute_Reference
70482933
RK
6808 (New_Occurrence_Of (Typ, Loc), Name_First, J)));
6809
6810 Evolve_And_Then (Cond,
6811 Make_Op_Eq (Loc,
6812 Left_Opnd =>
9a0ddeee 6813 Build_Attribute_Reference
fbf5a39b
AC
6814 (Duplicate_Subexpr_No_Checks (Obj),
6815 Name_Last, J),
70482933 6816 Right_Opnd =>
9a0ddeee 6817 Build_Attribute_Reference
70482933
RK
6818 (New_Occurrence_Of (Typ, Loc), Name_Last, J)));
6819 end loop;
fbf5a39b 6820 end Check_Subscripts;
70482933 6821
685094bf
RD
6822 -- These are the cases where constraint checks may be required,
6823 -- e.g. records with possible discriminants
70482933
RK
6824
6825 else
6826 -- Expand the test into a series of discriminant comparisons.
685094bf
RD
6827 -- The expression that is built is the negation of the one that
6828 -- is used for checking discriminant constraints.
70482933
RK
6829
6830 Obj := Relocate_Node (Left_Opnd (N));
6831
6832 if Has_Discriminants (Typ) then
6833 Cond := Make_Op_Not (Loc,
6834 Right_Opnd => Build_Discriminant_Checks (Obj, Typ));
70482933
RK
6835 else
6836 Cond := New_Occurrence_Of (Standard_True, Loc);
6837 end if;
11381028 6838 end if;
70482933 6839
11381028
AC
6840 if Is_Acc then
6841 if Check_Null_Exclusion then
6842 Cond := Make_And_Then (Loc,
6843 Left_Opnd =>
6844 Make_Op_Ne (Loc,
6845 Left_Opnd => Obj,
6846 Right_Opnd => Make_Null (Loc)),
6847 Right_Opnd => Cond);
6848 else
6849 Cond := Make_Or_Else (Loc,
6850 Left_Opnd =>
6851 Make_Op_Eq (Loc,
6852 Left_Opnd => Obj,
6853 Right_Opnd => Make_Null (Loc)),
6854 Right_Opnd => Cond);
6855 end if;
70482933 6856 end if;
6cce2156 6857
11381028
AC
6858 Rewrite (N, Cond);
6859 Analyze_And_Resolve (N, Restyp);
6860
6cce2156
GD
6861 -- Ada 2012 (AI05-0149): Handle membership tests applied to an
6862 -- expression of an anonymous access type. This can involve an
6863 -- accessibility test and a tagged type membership test in the
6864 -- case of tagged designated types.
6865
6866 if Ada_Version >= Ada_2012
6867 and then Is_Acc
6868 and then Ekind (Ltyp) = E_Anonymous_Access_Type
6869 then
6870 declare
6871 Expr_Entity : Entity_Id := Empty;
6872 New_N : Node_Id;
6873 Param_Level : Node_Id;
6874 Type_Level : Node_Id;
996c8821 6875
6cce2156
GD
6876 begin
6877 if Is_Entity_Name (Lop) then
6878 Expr_Entity := Param_Entity (Lop);
996c8821 6879
6cce2156
GD
6880 if not Present (Expr_Entity) then
6881 Expr_Entity := Entity (Lop);
6882 end if;
6883 end if;
6884
6885 -- If a conversion of the anonymous access value to the
6886 -- tested type would be illegal, then the result is False.
6887
6888 if not Valid_Conversion
6889 (Lop, Rtyp, Lop, Report_Errs => False)
6890 then
6891 Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
6892 Analyze_And_Resolve (N, Restyp);
6893
6894 -- Apply an accessibility check if the access object has an
6895 -- associated access level and when the level of the type is
6896 -- less deep than the level of the access parameter. This
d7e20130
JS
6897 -- can only occur for access parameters and stand-alone
6898 -- objects of an anonymous access type.
6cce2156
GD
6899
6900 else
66e97274
JS
6901 Param_Level := Accessibility_Level
6902 (Expr_Entity, Dynamic_Level);
6cce2156 6903
d7e20130
JS
6904 Type_Level :=
6905 Make_Integer_Literal (Loc, Type_Access_Level (Rtyp));
6cce2156 6906
d7e20130
JS
6907 -- Return True only if the accessibility level of the
6908 -- expression entity is not deeper than the level of
6909 -- the tested access type.
6cce2156 6910
d7e20130
JS
6911 Rewrite (N,
6912 Make_And_Then (Loc,
6913 Left_Opnd => Relocate_Node (N),
6914 Right_Opnd => Make_Op_Le (Loc,
6915 Left_Opnd => Param_Level,
6916 Right_Opnd => Type_Level)));
6cce2156 6917
d7e20130 6918 Analyze_And_Resolve (N);
6cce2156
GD
6919
6920 -- If the designated type is tagged, do tagged membership
6921 -- operation.
6922
6cce2156 6923 if Is_Tagged_Type (Typ) then
6cce2156 6924
535a8637 6925 -- No expansion will be performed for VM targets, as
c7a494c9 6926 -- the VM back ends will handle the membership tests
69d8d8b4 6927 -- directly.
6cce2156
GD
6928
6929 if Tagged_Type_Expansion then
6930
6931 -- Note that we have to pass Original_Node, because
6932 -- the membership test might already have been
6933 -- rewritten by earlier parts of membership test.
6934
6935 Tagged_Membership
6936 (Original_Node (N), SCIL_Node, New_N);
6937
6938 -- Update decoration of relocated node referenced
6939 -- by the SCIL node.
6940
6941 if Generate_SCIL and then Present (SCIL_Node) then
6942 Set_SCIL_Node (New_N, SCIL_Node);
6943 end if;
6944
6945 Rewrite (N,
6946 Make_And_Then (Loc,
6947 Left_Opnd => Relocate_Node (N),
6948 Right_Opnd => New_N));
6949
6950 Analyze_And_Resolve (N, Restyp);
6951 end if;
6952 end if;
6953 end if;
6954 end;
6955 end if;
70482933
RK
6956 end;
6957 end if;
4818e7b9
RD
6958
6959 -- At this point, we have done the processing required for the basic
6960 -- membership test, but not yet dealt with the predicate.
6961
6962 <<Leave>>
6963
c7532b2d
AC
6964 -- If a predicate is present, then we do the predicate test, but we
6965 -- most certainly want to omit this if we are within the predicate
a90bd866 6966 -- function itself, since otherwise we have an infinite recursion.
3d6db7f8
GD
6967 -- The check should also not be emitted when testing against a range
6968 -- (the check is only done when the right operand is a subtype; see
6969 -- RM12-4.5.2 (28.1/3-30/3)).
4818e7b9 6970
444656ce
ES
6971 Predicate_Check : declare
6972 function In_Range_Check return Boolean;
6973 -- Within an expanded range check that may raise Constraint_Error do
6974 -- not generate a predicate check as well. It is redundant because
6975 -- the context will add an explicit predicate check, and it will
6976 -- raise the wrong exception if it fails.
6977
6978 --------------------
6979 -- In_Range_Check --
6980 --------------------
6981
6982 function In_Range_Check return Boolean is
6983 P : Node_Id;
6984 begin
6985 P := Parent (N);
6986 while Present (P) loop
6987 if Nkind (P) = N_Raise_Constraint_Error then
6988 return True;
6989
6990 elsif Nkind (P) in N_Statement_Other_Than_Procedure_Call
6991 or else Nkind (P) = N_Procedure_Call_Statement
6992 or else Nkind (P) in N_Declaration
6993 then
6994 return False;
6995 end if;
6996
6997 P := Parent (P);
6998 end loop;
6999
7000 return False;
7001 end In_Range_Check;
7002
7003 -- Local variables
7004
c7532b2d 7005 PFunc : constant Entity_Id := Predicate_Function (Rtyp);
444656ce
ES
7006 R_Op : Node_Id;
7007
7008 -- Start of processing for Predicate_Check
4818e7b9 7009
c7532b2d
AC
7010 begin
7011 if Present (PFunc)
7012 and then Current_Scope /= PFunc
3d6db7f8 7013 and then Nkind (Rop) /= N_Range
c7532b2d 7014 then
444656ce
ES
7015 if not In_Range_Check then
7016 R_Op := Make_Predicate_Call (Rtyp, Lop, Mem => True);
7017 else
7018 R_Op := New_Occurrence_Of (Standard_True, Loc);
7019 end if;
7020
c7532b2d
AC
7021 Rewrite (N,
7022 Make_And_Then (Loc,
7023 Left_Opnd => Relocate_Node (N),
444656ce 7024 Right_Opnd => R_Op));
4818e7b9 7025
c7532b2d 7026 -- Analyze new expression, mark left operand as analyzed to
b2009d46
AC
7027 -- avoid infinite recursion adding predicate calls. Similarly,
7028 -- suppress further range checks on the call.
4818e7b9 7029
c7532b2d 7030 Set_Analyzed (Left_Opnd (N));
b2009d46 7031 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
4818e7b9 7032
c7532b2d
AC
7033 -- All done, skip attempt at compile time determination of result
7034
7035 return;
7036 end if;
444656ce 7037 end Predicate_Check;
70482933
RK
7038 end Expand_N_In;
7039
7040 --------------------------------
7041 -- Expand_N_Indexed_Component --
7042 --------------------------------
7043
7044 procedure Expand_N_Indexed_Component (N : Node_Id) is
7045 Loc : constant Source_Ptr := Sloc (N);
7046 Typ : constant Entity_Id := Etype (N);
7047 P : constant Node_Id := Prefix (N);
7048 T : constant Entity_Id := Etype (P);
7049
7050 begin
685094bf
RD
7051 -- A special optimization, if we have an indexed component that is
7052 -- selecting from a slice, then we can eliminate the slice, since, for
7053 -- example, x (i .. j)(k) is identical to x(k). The only difference is
7054 -- the range check required by the slice. The range check for the slice
7055 -- itself has already been generated. The range check for the
7056 -- subscripting operation is ensured by converting the subject to
7057 -- the subtype of the slice.
7058
7059 -- This optimization not only generates better code, avoiding slice
7060 -- messing especially in the packed case, but more importantly bypasses
7061 -- some problems in handling this peculiar case, for example, the issue
7062 -- of dealing specially with object renamings.
70482933 7063
45ec05e1
RD
7064 if Nkind (P) = N_Slice
7065
7066 -- This optimization is disabled for CodePeer because it can transform
7067 -- an index-check constraint_error into a range-check constraint_error
7068 -- and CodePeer cares about that distinction.
7069
7070 and then not CodePeer_Mode
7071 then
70482933
RK
7072 Rewrite (N,
7073 Make_Indexed_Component (Loc,
cc6f5d75 7074 Prefix => Prefix (P),
70482933
RK
7075 Expressions => New_List (
7076 Convert_To
7077 (Etype (First_Index (Etype (P))),
7078 First (Expressions (N))))));
7079 Analyze_And_Resolve (N, Typ);
7080 return;
7081 end if;
7082
b4592168
GD
7083 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
7084 -- function, then additional actuals must be passed.
7085
d4dfb005 7086 if Is_Build_In_Place_Function_Call (P) then
b4592168 7087 Make_Build_In_Place_Call_In_Anonymous_Context (P);
4ac62786
AC
7088
7089 -- Ada 2005 (AI-318-02): Specialization of the previous case for prefix
7090 -- containing build-in-place function calls whose returned object covers
7091 -- interface types.
7092
d4dfb005 7093 elsif Present (Unqual_BIP_Iface_Function_Call (P)) then
4ac62786 7094 Make_Build_In_Place_Iface_Call_In_Anonymous_Context (P);
b4592168
GD
7095 end if;
7096
fbf5a39b
AC
7097 -- Generate index and validity checks
7098
7099 Generate_Index_Checks (N);
7100
70482933
RK
7101 if Validity_Checks_On and then Validity_Check_Subscripts then
7102 Apply_Subscript_Validity_Checks (N);
7103 end if;
7104
5972791c
AC
7105 -- If selecting from an array with atomic components, and atomic sync
7106 -- is not suppressed for this array type, set atomic sync flag.
7107
f715a5bd
EB
7108 if (Has_Atomic_Components (T)
7109 and then not Atomic_Synchronization_Disabled (T))
5972791c
AC
7110 or else (Is_Atomic (Typ)
7111 and then not Atomic_Synchronization_Disabled (Typ))
e2f0522e
EB
7112 or else (Is_Entity_Name (P)
7113 and then Has_Atomic_Components (Entity (P))
7114 and then not Atomic_Synchronization_Disabled (Entity (P)))
5972791c 7115 then
4c318253 7116 Activate_Atomic_Synchronization (N);
5972791c
AC
7117 end if;
7118
b3f75672 7119 -- All done if the prefix is not a packed array implemented specially
70482933 7120
b3f75672
EB
7121 if not (Is_Packed (Etype (Prefix (N)))
7122 and then Present (Packed_Array_Impl_Type (Etype (Prefix (N)))))
7123 then
70482933
RK
7124 return;
7125 end if;
7126
7127 -- For packed arrays that are not bit-packed (i.e. the case of an array
8fc789c8 7128 -- with one or more index types with a non-contiguous enumeration type),
70482933
RK
7129 -- we can always use the normal packed element get circuit.
7130
7131 if not Is_Bit_Packed_Array (Etype (Prefix (N))) then
7132 Expand_Packed_Element_Reference (N);
7133 return;
7134 end if;
7135
8ca597af
RD
7136 -- For a reference to a component of a bit packed array, we convert it
7137 -- to a reference to the corresponding Packed_Array_Impl_Type. We only
7138 -- want to do this for simple references, and not for:
70482933 7139
685094bf
RD
7140 -- Left side of assignment, or prefix of left side of assignment, or
7141 -- prefix of the prefix, to handle packed arrays of packed arrays,
70482933
RK
7142 -- This case is handled in Exp_Ch5.Expand_N_Assignment_Statement
7143
7144 -- Renaming objects in renaming associations
7145 -- This case is handled when a use of the renamed variable occurs
7146
d21328a0 7147 -- Actual parameters for a subprogram call
70482933
RK
7148 -- This case is handled in Exp_Ch6.Expand_Actuals
7149
7150 -- The second expression in a 'Read attribute reference
7151
47d3b920 7152 -- The prefix of an address or bit or size attribute reference
70482933 7153
e8c84c8f
AC
7154 -- The following circuit detects these exceptions. Note that we need to
7155 -- deal with implicit dereferences when climbing up the parent chain,
7156 -- with the additional difficulty that the type of parents may have yet
7157 -- to be resolved since prefixes are usually resolved first.
70482933
RK
7158
7159 declare
7160 Child : Node_Id := N;
7161 Parnt : Node_Id := Parent (N);
7162
7163 begin
7164 loop
7165 if Nkind (Parnt) = N_Unchecked_Expression then
7166 null;
7167
d21328a0
EB
7168 elsif Nkind (Parnt) = N_Object_Renaming_Declaration then
7169 return;
7170
7171 elsif Nkind (Parnt) in N_Subprogram_Call
70482933 7172 or else (Nkind (Parnt) = N_Parameter_Association
d21328a0 7173 and then Nkind (Parent (Parnt)) in N_Subprogram_Call)
70482933
RK
7174 then
7175 return;
7176
7177 elsif Nkind (Parnt) = N_Attribute_Reference
4a08c95c
AC
7178 and then Attribute_Name (Parnt) in Name_Address
7179 | Name_Bit
7180 | Name_Size
70482933
RK
7181 and then Prefix (Parnt) = Child
7182 then
7183 return;
7184
7185 elsif Nkind (Parnt) = N_Assignment_Statement
7186 and then Name (Parnt) = Child
7187 then
7188 return;
7189
685094bf
RD
7190 -- If the expression is an index of an indexed component, it must
7191 -- be expanded regardless of context.
fbf5a39b
AC
7192
7193 elsif Nkind (Parnt) = N_Indexed_Component
7194 and then Child /= Prefix (Parnt)
7195 then
7196 Expand_Packed_Element_Reference (N);
7197 return;
7198
7199 elsif Nkind (Parent (Parnt)) = N_Assignment_Statement
7200 and then Name (Parent (Parnt)) = Parnt
7201 then
7202 return;
7203
70482933
RK
7204 elsif Nkind (Parnt) = N_Attribute_Reference
7205 and then Attribute_Name (Parnt) = Name_Read
7206 and then Next (First (Expressions (Parnt))) = Child
7207 then
7208 return;
7209
e8c84c8f
AC
7210 elsif Nkind (Parnt) = N_Indexed_Component
7211 and then Prefix (Parnt) = Child
7212 then
7213 null;
7214
7215 elsif Nkind (Parnt) = N_Selected_Component
533369aa 7216 and then Prefix (Parnt) = Child
e8c84c8f
AC
7217 and then not (Present (Etype (Selector_Name (Parnt)))
7218 and then
7219 Is_Access_Type (Etype (Selector_Name (Parnt))))
70482933
RK
7220 then
7221 null;
7222
e8c84c8f
AC
7223 -- If the parent is a dereference, either implicit or explicit,
7224 -- then the packed reference needs to be expanded.
7225
70482933
RK
7226 else
7227 Expand_Packed_Element_Reference (N);
7228 return;
7229 end if;
7230
685094bf
RD
7231 -- Keep looking up tree for unchecked expression, or if we are the
7232 -- prefix of a possible assignment left side.
70482933
RK
7233
7234 Child := Parnt;
7235 Parnt := Parent (Child);
7236 end loop;
7237 end;
70482933
RK
7238 end Expand_N_Indexed_Component;
7239
7240 ---------------------
7241 -- Expand_N_Not_In --
7242 ---------------------
7243
7244 -- Replace a not in b by not (a in b) so that the expansions for (a in b)
7245 -- can be done. This avoids needing to duplicate this expansion code.
7246
7247 procedure Expand_N_Not_In (N : Node_Id) is
630d30e9
RD
7248 Loc : constant Source_Ptr := Sloc (N);
7249 Typ : constant Entity_Id := Etype (N);
7250 Cfs : constant Boolean := Comes_From_Source (N);
70482933
RK
7251
7252 begin
7253 Rewrite (N,
7254 Make_Op_Not (Loc,
7255 Right_Opnd =>
7256 Make_In (Loc,
7257 Left_Opnd => Left_Opnd (N),
d766cee3 7258 Right_Opnd => Right_Opnd (N))));
630d30e9 7259
197e4514
AC
7260 -- If this is a set membership, preserve list of alternatives
7261
7262 Set_Alternatives (Right_Opnd (N), Alternatives (Original_Node (N)));
7263
d766cee3 7264 -- We want this to appear as coming from source if original does (see
8fc789c8 7265 -- transformations in Expand_N_In).
630d30e9
RD
7266
7267 Set_Comes_From_Source (N, Cfs);
7268 Set_Comes_From_Source (Right_Opnd (N), Cfs);
7269
8fc789c8 7270 -- Now analyze transformed node
630d30e9 7271
70482933
RK
7272 Analyze_And_Resolve (N, Typ);
7273 end Expand_N_Not_In;
7274
7275 -------------------
7276 -- Expand_N_Null --
7277 -------------------
7278
a3f2babd
AC
7279 -- The only replacement required is for the case of a null of a type that
7280 -- is an access to protected subprogram, or a subtype thereof. We represent
7281 -- such access values as a record, and so we must replace the occurrence of
7282 -- null by the equivalent record (with a null address and a null pointer in
c7a494c9 7283 -- it), so that the back end creates the proper value.
70482933
RK
7284
7285 procedure Expand_N_Null (N : Node_Id) is
7286 Loc : constant Source_Ptr := Sloc (N);
a3f2babd 7287 Typ : constant Entity_Id := Base_Type (Etype (N));
70482933
RK
7288 Agg : Node_Id;
7289
7290 begin
26bff3d9 7291 if Is_Access_Protected_Subprogram_Type (Typ) then
70482933
RK
7292 Agg :=
7293 Make_Aggregate (Loc,
7294 Expressions => New_List (
7295 New_Occurrence_Of (RTE (RE_Null_Address), Loc),
7296 Make_Null (Loc)));
7297
7298 Rewrite (N, Agg);
7299 Analyze_And_Resolve (N, Equivalent_Type (Typ));
7300
685094bf
RD
7301 -- For subsequent semantic analysis, the node must retain its type.
7302 -- Gigi in any case replaces this type by the corresponding record
7303 -- type before processing the node.
70482933
RK
7304
7305 Set_Etype (N, Typ);
7306 end if;
fbf5a39b
AC
7307
7308 exception
7309 when RE_Not_Available =>
7310 return;
70482933
RK
7311 end Expand_N_Null;
7312
7313 ---------------------
7314 -- Expand_N_Op_Abs --
7315 ---------------------
7316
7317 procedure Expand_N_Op_Abs (N : Node_Id) is
7318 Loc : constant Source_Ptr := Sloc (N);
cc6f5d75 7319 Expr : constant Node_Id := Right_Opnd (N);
6c8e4f7e 7320 Typ : constant Entity_Id := Etype (N);
70482933
RK
7321
7322 begin
7323 Unary_Op_Validity_Checks (N);
7324
b6b5cca8
AC
7325 -- Check for MINIMIZED/ELIMINATED overflow mode
7326
7327 if Minimized_Eliminated_Overflow_Check (N) then
7328 Apply_Arithmetic_Overflow_Check (N);
7329 return;
7330 end if;
7331
6c8e4f7e
EB
7332 -- Try to narrow the operation
7333
7334 if Typ = Universal_Integer then
7335 Narrow_Large_Operation (N);
7336
7337 if Nkind (N) /= N_Op_Abs then
7338 return;
7339 end if;
7340 end if;
7341
70482933
RK
7342 -- Deal with software overflow checking
7343
6c8e4f7e 7344 if Is_Signed_Integer_Type (Typ)
533369aa 7345 and then Do_Overflow_Check (N)
70482933 7346 then
685094bf
RD
7347 -- The only case to worry about is when the argument is equal to the
7348 -- largest negative number, so what we do is to insert the check:
70482933 7349
fbf5a39b 7350 -- [constraint_error when Expr = typ'Base'First]
70482933
RK
7351
7352 -- with the usual Duplicate_Subexpr use coding for expr
7353
fbf5a39b
AC
7354 Insert_Action (N,
7355 Make_Raise_Constraint_Error (Loc,
7356 Condition =>
7357 Make_Op_Eq (Loc,
70482933 7358 Left_Opnd => Duplicate_Subexpr (Expr),
fbf5a39b
AC
7359 Right_Opnd =>
7360 Make_Attribute_Reference (Loc,
cc6f5d75 7361 Prefix =>
fbf5a39b
AC
7362 New_Occurrence_Of (Base_Type (Etype (Expr)), Loc),
7363 Attribute_Name => Name_First)),
7364 Reason => CE_Overflow_Check_Failed));
c35c40e7
RK
7365
7366 Set_Do_Overflow_Check (N, False);
fbf5a39b 7367 end if;
70482933
RK
7368 end Expand_N_Op_Abs;
7369
7370 ---------------------
7371 -- Expand_N_Op_Add --
7372 ---------------------
7373
7374 procedure Expand_N_Op_Add (N : Node_Id) is
7375 Typ : constant Entity_Id := Etype (N);
7376
7377 begin
7378 Binary_Op_Validity_Checks (N);
7379
b6b5cca8
AC
7380 -- Check for MINIMIZED/ELIMINATED overflow mode
7381
7382 if Minimized_Eliminated_Overflow_Check (N) then
7383 Apply_Arithmetic_Overflow_Check (N);
7384 return;
7385 end if;
7386
70482933
RK
7387 -- N + 0 = 0 + N = N for integer types
7388
7389 if Is_Integer_Type (Typ) then
7390 if Compile_Time_Known_Value (Right_Opnd (N))
7391 and then Expr_Value (Right_Opnd (N)) = Uint_0
7392 then
7393 Rewrite (N, Left_Opnd (N));
7394 return;
7395
7396 elsif Compile_Time_Known_Value (Left_Opnd (N))
7397 and then Expr_Value (Left_Opnd (N)) = Uint_0
7398 then
7399 Rewrite (N, Right_Opnd (N));
7400 return;
7401 end if;
7402 end if;
7403
6c8e4f7e
EB
7404 -- Try to narrow the operation
7405
7406 if Typ = Universal_Integer then
7407 Narrow_Large_Operation (N);
7408
7409 if Nkind (N) /= N_Op_Add then
7410 return;
7411 end if;
7412 end if;
7413
fbf5a39b 7414 -- Arithmetic overflow checks for signed integer/fixed point types
70482933 7415
761f7dcb 7416 if Is_Signed_Integer_Type (Typ) or else Is_Fixed_Point_Type (Typ) then
70482933
RK
7417 Apply_Arithmetic_Overflow_Check (N);
7418 return;
70482933 7419 end if;
dfaff97b
RD
7420
7421 -- Overflow checks for floating-point if -gnateF mode active
7422
7423 Check_Float_Op_Overflow (N);
05dbb83f 7424
f4ac86dd 7425 Expand_Nonbinary_Modular_Op (N);
70482933
RK
7426 end Expand_N_Op_Add;
7427
7428 ---------------------
7429 -- Expand_N_Op_And --
7430 ---------------------
7431
7432 procedure Expand_N_Op_And (N : Node_Id) is
7433 Typ : constant Entity_Id := Etype (N);
7434
7435 begin
7436 Binary_Op_Validity_Checks (N);
7437
7438 if Is_Array_Type (Etype (N)) then
7439 Expand_Boolean_Operator (N);
7440
7441 elsif Is_Boolean_Type (Etype (N)) then
f2d10a02
AC
7442 Adjust_Condition (Left_Opnd (N));
7443 Adjust_Condition (Right_Opnd (N));
7444 Set_Etype (N, Standard_Boolean);
7445 Adjust_Result_Type (N, Typ);
437f8c1e
AC
7446
7447 elsif Is_Intrinsic_Subprogram (Entity (N)) then
7448 Expand_Intrinsic_Call (N, Entity (N));
05dbb83f
AC
7449 end if;
7450
f4ac86dd 7451 Expand_Nonbinary_Modular_Op (N);
70482933
RK
7452 end Expand_N_Op_And;
7453
7454 ------------------------
7455 -- Expand_N_Op_Concat --
7456 ------------------------
7457
7458 procedure Expand_N_Op_Concat (N : Node_Id) is
70482933
RK
7459 Opnds : List_Id;
7460 -- List of operands to be concatenated
7461
70482933 7462 Cnode : Node_Id;
685094bf
RD
7463 -- Node which is to be replaced by the result of concatenating the nodes
7464 -- in the list Opnds.
70482933 7465
70482933 7466 begin
fbf5a39b
AC
7467 -- Ensure validity of both operands
7468
70482933
RK
7469 Binary_Op_Validity_Checks (N);
7470
685094bf
RD
7471 -- If we are the left operand of a concatenation higher up the tree,
7472 -- then do nothing for now, since we want to deal with a series of
7473 -- concatenations as a unit.
70482933
RK
7474
7475 if Nkind (Parent (N)) = N_Op_Concat
7476 and then N = Left_Opnd (Parent (N))
7477 then
7478 return;
7479 end if;
7480
7481 -- We get here with a concatenation whose left operand may be a
7482 -- concatenation itself with a consistent type. We need to process
7483 -- these concatenation operands from left to right, which means
7484 -- from the deepest node in the tree to the highest node.
7485
7486 Cnode := N;
7487 while Nkind (Left_Opnd (Cnode)) = N_Op_Concat loop
7488 Cnode := Left_Opnd (Cnode);
7489 end loop;
7490
64425dff
BD
7491 -- Now Cnode is the deepest concatenation, and its parents are the
7492 -- concatenation nodes above, so now we process bottom up, doing the
64425dff 7493 -- operands.
70482933 7494
df46b832
AC
7495 -- The outer loop runs more than once if more than one concatenation
7496 -- type is involved.
70482933
RK
7497
7498 Outer : loop
7499 Opnds := New_List (Left_Opnd (Cnode), Right_Opnd (Cnode));
7500 Set_Parent (Opnds, N);
7501
df46b832 7502 -- The inner loop gathers concatenation operands
70482933
RK
7503
7504 Inner : while Cnode /= N
70482933
RK
7505 and then Base_Type (Etype (Cnode)) =
7506 Base_Type (Etype (Parent (Cnode)))
7507 loop
7508 Cnode := Parent (Cnode);
7509 Append (Right_Opnd (Cnode), Opnds);
7510 end loop Inner;
7511
43c58950
AC
7512 -- Note: The following code is a temporary workaround for N731-034
7513 -- and N829-028 and will be kept until the general issue of internal
7514 -- symbol serialization is addressed. The workaround is kept under a
7515 -- debug switch to avoid permiating into the general case.
7516
7517 -- Wrap the node to concatenate into an expression actions node to
7518 -- keep it nicely packaged. This is useful in the case of an assert
7519 -- pragma with a concatenation where we want to be able to delete
7520 -- the concatenation and all its expansion stuff.
7521
7522 if Debug_Flag_Dot_H then
7523 declare
683af98c 7524 Cnod : constant Node_Id := New_Copy_Tree (Cnode);
43c58950
AC
7525 Typ : constant Entity_Id := Base_Type (Etype (Cnode));
7526
7527 begin
7528 -- Note: use Rewrite rather than Replace here, so that for
7529 -- example Why_Not_Static can find the original concatenation
7530 -- node OK!
7531
7532 Rewrite (Cnode,
7533 Make_Expression_With_Actions (Sloc (Cnode),
7534 Actions => New_List (Make_Null_Statement (Sloc (Cnode))),
7535 Expression => Cnod));
7536
7537 Expand_Concatenate (Cnod, Opnds);
7538 Analyze_And_Resolve (Cnode, Typ);
7539 end;
7540
7541 -- Default case
7542
7543 else
7544 Expand_Concatenate (Cnode, Opnds);
7545 end if;
70482933
RK
7546
7547 exit Outer when Cnode = N;
7548 Cnode := Parent (Cnode);
7549 end loop Outer;
7550 end Expand_N_Op_Concat;
7551
7552 ------------------------
7553 -- Expand_N_Op_Divide --
7554 ------------------------
7555
7556 procedure Expand_N_Op_Divide (N : Node_Id) is
f82944b7
JM
7557 Loc : constant Source_Ptr := Sloc (N);
7558 Lopnd : constant Node_Id := Left_Opnd (N);
7559 Ropnd : constant Node_Id := Right_Opnd (N);
7560 Ltyp : constant Entity_Id := Etype (Lopnd);
7561 Rtyp : constant Entity_Id := Etype (Ropnd);
7562 Typ : Entity_Id := Etype (N);
7563 Rknow : constant Boolean := Is_Integer_Type (Typ)
7564 and then
7565 Compile_Time_Known_Value (Ropnd);
7566 Rval : Uint;
70482933
RK
7567
7568 begin
7569 Binary_Op_Validity_Checks (N);
7570
b6b5cca8
AC
7571 -- Check for MINIMIZED/ELIMINATED overflow mode
7572
7573 if Minimized_Eliminated_Overflow_Check (N) then
7574 Apply_Arithmetic_Overflow_Check (N);
7575 return;
7576 end if;
7577
7578 -- Otherwise proceed with expansion of division
7579
f82944b7
JM
7580 if Rknow then
7581 Rval := Expr_Value (Ropnd);
7582 end if;
7583
70482933
RK
7584 -- N / 1 = N for integer types
7585
f82944b7
JM
7586 if Rknow and then Rval = Uint_1 then
7587 Rewrite (N, Lopnd);
70482933
RK
7588 return;
7589 end if;
7590
6c8e4f7e
EB
7591 -- Try to narrow the operation
7592
7593 if Typ = Universal_Integer then
7594 Narrow_Large_Operation (N);
7595
7596 if Nkind (N) /= N_Op_Divide then
7597 return;
7598 end if;
7599 end if;
7600
70482933
RK
7601 -- Convert x / 2 ** y to Shift_Right (x, y). Note that the fact that
7602 -- Is_Power_Of_2_For_Shift is set means that we know that our left
7603 -- operand is an unsigned integer, as required for this to work.
7604
f82944b7
JM
7605 if Nkind (Ropnd) = N_Op_Expon
7606 and then Is_Power_Of_2_For_Shift (Ropnd)
fbf5a39b
AC
7607
7608 -- We cannot do this transformation in configurable run time mode if we
51bf9bdf 7609 -- have 64-bit integers and long shifts are not available.
fbf5a39b 7610
761f7dcb 7611 and then (Esize (Ltyp) <= 32 or else Support_Long_Shifts_On_Target)
70482933
RK
7612 then
7613 Rewrite (N,
7614 Make_Op_Shift_Right (Loc,
f82944b7 7615 Left_Opnd => Lopnd,
70482933 7616 Right_Opnd =>
f82944b7 7617 Convert_To (Standard_Natural, Right_Opnd (Ropnd))));
70482933
RK
7618 Analyze_And_Resolve (N, Typ);
7619 return;
7620 end if;
7621
7622 -- Do required fixup of universal fixed operation
7623
7624 if Typ = Universal_Fixed then
7625 Fixup_Universal_Fixed_Operation (N);
7626 Typ := Etype (N);
7627 end if;
7628
7629 -- Divisions with fixed-point results
7630
7631 if Is_Fixed_Point_Type (Typ) then
7632
fa54f4da
EB
7633 if Is_Integer_Type (Rtyp) then
7634 Expand_Divide_Fixed_By_Integer_Giving_Fixed (N);
7635 else
7636 Expand_Divide_Fixed_By_Fixed_Giving_Fixed (N);
8223b654
AC
7637 end if;
7638
21f30884
AC
7639 -- Deal with divide-by-zero check if back end cannot handle them
7640 -- and the flag is set indicating that we need such a check. Note
7641 -- that we don't need to bother here with the case of mixed-mode
7642 -- (Right operand an integer type), since these will be rewritten
7643 -- with conversions to a divide with a fixed-point right operand.
7644
8223b654
AC
7645 if Nkind (N) = N_Op_Divide
7646 and then Do_Division_Check (N)
21f30884
AC
7647 and then not Backend_Divide_Checks_On_Target
7648 and then not Is_Integer_Type (Rtyp)
7649 then
7650 Set_Do_Division_Check (N, False);
7651 Insert_Action (N,
7652 Make_Raise_Constraint_Error (Loc,
7653 Condition =>
7654 Make_Op_Eq (Loc,
7655 Left_Opnd => Duplicate_Subexpr_Move_Checks (Ropnd),
7656 Right_Opnd => Make_Real_Literal (Loc, Ureal_0)),
7657 Reason => CE_Divide_By_Zero));
7658 end if;
7659
fa54f4da 7660 -- Other cases of division of fixed-point operands
70482933 7661
fa54f4da 7662 elsif Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp) then
70482933
RK
7663 if Is_Integer_Type (Typ) then
7664 Expand_Divide_Fixed_By_Fixed_Giving_Integer (N);
7665 else
7666 pragma Assert (Is_Floating_Point_Type (Typ));
7667 Expand_Divide_Fixed_By_Fixed_Giving_Float (N);
7668 end if;
7669
685094bf
RD
7670 -- Mixed-mode operations can appear in a non-static universal context,
7671 -- in which case the integer argument must be converted explicitly.
70482933 7672
533369aa 7673 elsif Typ = Universal_Real and then Is_Integer_Type (Rtyp) then
f82944b7
JM
7674 Rewrite (Ropnd,
7675 Convert_To (Universal_Real, Relocate_Node (Ropnd)));
70482933 7676
f82944b7 7677 Analyze_And_Resolve (Ropnd, Universal_Real);
70482933 7678
533369aa 7679 elsif Typ = Universal_Real and then Is_Integer_Type (Ltyp) then
f82944b7
JM
7680 Rewrite (Lopnd,
7681 Convert_To (Universal_Real, Relocate_Node (Lopnd)));
70482933 7682
f82944b7 7683 Analyze_And_Resolve (Lopnd, Universal_Real);
70482933 7684
f02b8bb8 7685 -- Non-fixed point cases, do integer zero divide and overflow checks
70482933
RK
7686
7687 elsif Is_Integer_Type (Typ) then
a91e9ac7 7688 Apply_Divide_Checks (N);
70482933 7689 end if;
dfaff97b
RD
7690
7691 -- Overflow checks for floating-point if -gnateF mode active
7692
7693 Check_Float_Op_Overflow (N);
05dbb83f 7694
f4ac86dd 7695 Expand_Nonbinary_Modular_Op (N);
70482933
RK
7696 end Expand_N_Op_Divide;
7697
7698 --------------------
7699 -- Expand_N_Op_Eq --
7700 --------------------
7701
7702 procedure Expand_N_Op_Eq (N : Node_Id) is
fbf5a39b
AC
7703 Loc : constant Source_Ptr := Sloc (N);
7704 Typ : constant Entity_Id := Etype (N);
7705 Lhs : constant Node_Id := Left_Opnd (N);
7706 Rhs : constant Node_Id := Right_Opnd (N);
7707 Bodies : constant List_Id := New_List;
7708 A_Typ : constant Entity_Id := Etype (Lhs);
7709
70482933
RK
7710 procedure Build_Equality_Call (Eq : Entity_Id);
7711 -- If a constructed equality exists for the type or for its parent,
7712 -- build and analyze call, adding conversions if the operation is
7713 -- inherited.
7714
d7c37f45
SB
7715 function Is_Equality (Subp : Entity_Id;
7716 Typ : Entity_Id := Empty) return Boolean;
7717 -- Determine whether arbitrary Entity_Id denotes a function with the
7718 -- right name and profile for an equality op, specifically for the
7719 -- base type Typ if Typ is nonempty.
7720
e1a20c09
HK
7721 function Find_Equality (Prims : Elist_Id) return Entity_Id;
7722 -- Find a primitive equality function within primitive operation list
7723 -- Prims.
7724
d7c37f45
SB
7725 function User_Defined_Primitive_Equality_Op
7726 (Typ : Entity_Id) return Entity_Id;
7727 -- Find a user-defined primitive equality function for a given untagged
7728 -- record type, ignoring visibility. Return Empty if no such op found.
7729
e1a20c09 7730 function Has_Unconstrained_UU_Component (Typ : Entity_Id) return Boolean;
8fc789c8 7731 -- Determines whether a type has a subcomponent of an unconstrained
5d09245e
AC
7732 -- Unchecked_Union subtype. Typ is a record type.
7733
70482933
RK
7734 -------------------------
7735 -- Build_Equality_Call --
7736 -------------------------
7737
7738 procedure Build_Equality_Call (Eq : Entity_Id) is
7739 Op_Type : constant Entity_Id := Etype (First_Formal (Eq));
cc6f5d75
AC
7740 L_Exp : Node_Id := Relocate_Node (Lhs);
7741 R_Exp : Node_Id := Relocate_Node (Rhs);
70482933
RK
7742
7743 begin
dda38714
AC
7744 -- Adjust operands if necessary to comparison type
7745
70482933
RK
7746 if Base_Type (Op_Type) /= Base_Type (A_Typ)
7747 and then not Is_Class_Wide_Type (A_Typ)
7748 then
7749 L_Exp := OK_Convert_To (Op_Type, L_Exp);
7750 R_Exp := OK_Convert_To (Op_Type, R_Exp);
7751 end if;
7752
5d09245e
AC
7753 -- If we have an Unchecked_Union, we need to add the inferred
7754 -- discriminant values as actuals in the function call. At this
7755 -- point, the expansion has determined that both operands have
7756 -- inferable discriminants.
7757
7758 if Is_Unchecked_Union (Op_Type) then
7759 declare
fa1608c2
ES
7760 Lhs_Type : constant Node_Id := Etype (L_Exp);
7761 Rhs_Type : constant Node_Id := Etype (R_Exp);
7762
7763 Lhs_Discr_Vals : Elist_Id;
7764 -- List of inferred discriminant values for left operand.
7765
7766 Rhs_Discr_Vals : Elist_Id;
7767 -- List of inferred discriminant values for right operand.
7768
7769 Discr : Entity_Id;
5d09245e
AC
7770
7771 begin
fa1608c2
ES
7772 Lhs_Discr_Vals := New_Elmt_List;
7773 Rhs_Discr_Vals := New_Elmt_List;
7774
5d09245e
AC
7775 -- Per-object constrained selected components require special
7776 -- attention. If the enclosing scope of the component is an
f02b8bb8 7777 -- Unchecked_Union, we cannot reference its discriminants
fa1608c2
ES
7778 -- directly. This is why we use the extra parameters of the
7779 -- equality function of the enclosing Unchecked_Union.
5d09245e
AC
7780
7781 -- type UU_Type (Discr : Integer := 0) is
7782 -- . . .
7783 -- end record;
7784 -- pragma Unchecked_Union (UU_Type);
7785
7786 -- 1. Unchecked_Union enclosing record:
7787
7788 -- type Enclosing_UU_Type (Discr : Integer := 0) is record
7789 -- . . .
7790 -- Comp : UU_Type (Discr);
7791 -- . . .
7792 -- end Enclosing_UU_Type;
7793 -- pragma Unchecked_Union (Enclosing_UU_Type);
7794
7795 -- Obj1 : Enclosing_UU_Type;
7796 -- Obj2 : Enclosing_UU_Type (1);
7797
2717634d 7798 -- [. . .] Obj1 = Obj2 [. . .]
5d09245e
AC
7799
7800 -- Generated code:
7801
7802 -- if not (uu_typeEQ (obj1.comp, obj2.comp, a, b)) then
7803
7804 -- A and B are the formal parameters of the equality function
7805 -- of Enclosing_UU_Type. The function always has two extra
fa1608c2
ES
7806 -- formals to capture the inferred discriminant values for
7807 -- each discriminant of the type.
5d09245e
AC
7808
7809 -- 2. Non-Unchecked_Union enclosing record:
7810
7811 -- type
7812 -- Enclosing_Non_UU_Type (Discr : Integer := 0)
7813 -- is record
7814 -- . . .
7815 -- Comp : UU_Type (Discr);
7816 -- . . .
7817 -- end Enclosing_Non_UU_Type;
7818
7819 -- Obj1 : Enclosing_Non_UU_Type;
7820 -- Obj2 : Enclosing_Non_UU_Type (1);
7821
64ac53f4 7822 -- ... Obj1 = Obj2 ...
5d09245e
AC
7823
7824 -- Generated code:
7825
7826 -- if not (uu_typeEQ (obj1.comp, obj2.comp,
7827 -- obj1.discr, obj2.discr)) then
7828
7829 -- In this case we can directly reference the discriminants of
7830 -- the enclosing record.
7831
fa1608c2 7832 -- Process left operand of equality
5d09245e
AC
7833
7834 if Nkind (Lhs) = N_Selected_Component
533369aa
AC
7835 and then
7836 Has_Per_Object_Constraint (Entity (Selector_Name (Lhs)))
5d09245e 7837 then
fa1608c2
ES
7838 -- If enclosing record is an Unchecked_Union, use formals
7839 -- corresponding to each discriminant. The name of the
7840 -- formal is that of the discriminant, with added suffix,
7841 -- see Exp_Ch3.Build_Record_Equality for details.
5d09245e 7842
dda38714 7843 if Is_Unchecked_Union (Scope (Entity (Selector_Name (Lhs))))
5d09245e 7844 then
fa1608c2
ES
7845 Discr :=
7846 First_Discriminant
7847 (Scope (Entity (Selector_Name (Lhs))));
7848 while Present (Discr) loop
cc6f5d75
AC
7849 Append_Elmt
7850 (Make_Identifier (Loc,
7851 Chars => New_External_Name (Chars (Discr), 'A')),
7852 To => Lhs_Discr_Vals);
fa1608c2
ES
7853 Next_Discriminant (Discr);
7854 end loop;
5d09245e 7855
fa1608c2
ES
7856 -- If enclosing record is of a non-Unchecked_Union type, it
7857 -- is possible to reference its discriminants directly.
5d09245e
AC
7858
7859 else
fa1608c2
ES
7860 Discr := First_Discriminant (Lhs_Type);
7861 while Present (Discr) loop
cc6f5d75
AC
7862 Append_Elmt
7863 (Make_Selected_Component (Loc,
7864 Prefix => Prefix (Lhs),
7865 Selector_Name =>
7866 New_Copy
7867 (Get_Discriminant_Value (Discr,
7868 Lhs_Type,
7869 Stored_Constraint (Lhs_Type)))),
7870 To => Lhs_Discr_Vals);
fa1608c2
ES
7871 Next_Discriminant (Discr);
7872 end loop;
5d09245e
AC
7873 end if;
7874
fa1608c2
ES
7875 -- Otherwise operand is on object with a constrained type.
7876 -- Infer the discriminant values from the constraint.
5d09245e
AC
7877
7878 else
fa1608c2
ES
7879 Discr := First_Discriminant (Lhs_Type);
7880 while Present (Discr) loop
cc6f5d75
AC
7881 Append_Elmt
7882 (New_Copy
7883 (Get_Discriminant_Value (Discr,
fa1608c2
ES
7884 Lhs_Type,
7885 Stored_Constraint (Lhs_Type))),
cc6f5d75 7886 To => Lhs_Discr_Vals);
fa1608c2
ES
7887 Next_Discriminant (Discr);
7888 end loop;
5d09245e
AC
7889 end if;
7890
fa1608c2 7891 -- Similar processing for right operand of equality
5d09245e
AC
7892
7893 if Nkind (Rhs) = N_Selected_Component
533369aa
AC
7894 and then
7895 Has_Per_Object_Constraint (Entity (Selector_Name (Rhs)))
5d09245e 7896 then
5e1c00fa 7897 if Is_Unchecked_Union
cc6f5d75 7898 (Scope (Entity (Selector_Name (Rhs))))
5d09245e 7899 then
fa1608c2
ES
7900 Discr :=
7901 First_Discriminant
7902 (Scope (Entity (Selector_Name (Rhs))));
7903 while Present (Discr) loop
cc6f5d75
AC
7904 Append_Elmt
7905 (Make_Identifier (Loc,
7906 Chars => New_External_Name (Chars (Discr), 'B')),
7907 To => Rhs_Discr_Vals);
fa1608c2
ES
7908 Next_Discriminant (Discr);
7909 end loop;
5d09245e
AC
7910
7911 else
fa1608c2
ES
7912 Discr := First_Discriminant (Rhs_Type);
7913 while Present (Discr) loop
cc6f5d75
AC
7914 Append_Elmt
7915 (Make_Selected_Component (Loc,
7916 Prefix => Prefix (Rhs),
7917 Selector_Name =>
7918 New_Copy (Get_Discriminant_Value
7919 (Discr,
7920 Rhs_Type,
7921 Stored_Constraint (Rhs_Type)))),
7922 To => Rhs_Discr_Vals);
fa1608c2
ES
7923 Next_Discriminant (Discr);
7924 end loop;
5d09245e 7925 end if;
5d09245e 7926
fa1608c2
ES
7927 else
7928 Discr := First_Discriminant (Rhs_Type);
7929 while Present (Discr) loop
cc6f5d75
AC
7930 Append_Elmt
7931 (New_Copy (Get_Discriminant_Value
7932 (Discr,
7933 Rhs_Type,
7934 Stored_Constraint (Rhs_Type))),
7935 To => Rhs_Discr_Vals);
fa1608c2
ES
7936 Next_Discriminant (Discr);
7937 end loop;
5d09245e
AC
7938 end if;
7939
fa1608c2
ES
7940 -- Now merge the list of discriminant values so that values
7941 -- of corresponding discriminants are adjacent.
7942
7943 declare
7944 Params : List_Id;
7945 L_Elmt : Elmt_Id;
7946 R_Elmt : Elmt_Id;
7947
7948 begin
7949 Params := New_List (L_Exp, R_Exp);
7950 L_Elmt := First_Elmt (Lhs_Discr_Vals);
7951 R_Elmt := First_Elmt (Rhs_Discr_Vals);
7952 while Present (L_Elmt) loop
7953 Append_To (Params, Node (L_Elmt));
7954 Append_To (Params, Node (R_Elmt));
7955 Next_Elmt (L_Elmt);
7956 Next_Elmt (R_Elmt);
7957 end loop;
7958
7959 Rewrite (N,
7960 Make_Function_Call (Loc,
e4494292 7961 Name => New_Occurrence_Of (Eq, Loc),
fa1608c2
ES
7962 Parameter_Associations => Params));
7963 end;
5d09245e
AC
7964 end;
7965
7966 -- Normal case, not an unchecked union
7967
7968 else
7969 Rewrite (N,
7970 Make_Function_Call (Loc,
e4494292 7971 Name => New_Occurrence_Of (Eq, Loc),
5d09245e
AC
7972 Parameter_Associations => New_List (L_Exp, R_Exp)));
7973 end if;
70482933
RK
7974
7975 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
7976 end Build_Equality_Call;
7977
d7c37f45
SB
7978 -----------------
7979 -- Is_Equality --
7980 -----------------
7981
7982 function Is_Equality (Subp : Entity_Id;
7983 Typ : Entity_Id := Empty) return Boolean is
7984 Formal_1 : Entity_Id;
7985 Formal_2 : Entity_Id;
7986 begin
7987 -- The equality function carries name "=", returns Boolean, and has
7988 -- exactly two formal parameters of an identical type.
7989
7990 if Ekind (Subp) = E_Function
7991 and then Chars (Subp) = Name_Op_Eq
7992 and then Base_Type (Etype (Subp)) = Standard_Boolean
7993 then
7994 Formal_1 := First_Formal (Subp);
7995 Formal_2 := Empty;
7996
7997 if Present (Formal_1) then
7998 Formal_2 := Next_Formal (Formal_1);
7999 end if;
8000
8001 return
8002 Present (Formal_1)
8003 and then Present (Formal_2)
8004 and then No (Next_Formal (Formal_2))
8005 and then Base_Type (Etype (Formal_1)) =
8006 Base_Type (Etype (Formal_2))
8007 and then
8008 (not Present (Typ)
8009 or else Implementation_Base_Type (Etype (Formal_1)) = Typ);
8010 end if;
8011
8012 return False;
8013 end Is_Equality;
8014
e1a20c09
HK
8015 -------------------
8016 -- Find_Equality --
8017 -------------------
8018
8019 function Find_Equality (Prims : Elist_Id) return Entity_Id is
0715a2a8
HK
8020 function Find_Aliased_Equality (Prim : Entity_Id) return Entity_Id;
8021 -- Find an equality in a possible alias chain starting from primitive
8022 -- operation Prim.
e1a20c09 8023
0715a2a8
HK
8024 ---------------------------
8025 -- Find_Aliased_Equality --
8026 ---------------------------
e1a20c09 8027
0715a2a8
HK
8028 function Find_Aliased_Equality (Prim : Entity_Id) return Entity_Id is
8029 Candid : Entity_Id;
e1a20c09 8030
0715a2a8
HK
8031 begin
8032 -- Inspect each candidate in the alias chain, checking whether it
8033 -- denotes an equality.
e1a20c09 8034
0715a2a8
HK
8035 Candid := Prim;
8036 while Present (Candid) loop
8037 if Is_Equality (Candid) then
8038 return Candid;
8039 end if;
e1a20c09 8040
0715a2a8
HK
8041 Candid := Alias (Candid);
8042 end loop;
e1a20c09 8043
0715a2a8
HK
8044 return Empty;
8045 end Find_Aliased_Equality;
e1a20c09 8046
0715a2a8
HK
8047 -- Local variables
8048
8049 Eq_Prim : Entity_Id;
8050 Prim_Elmt : Elmt_Id;
8051
8052 -- Start of processing for Find_Equality
8053
8054 begin
8055 -- Assume that the tagged type lacks an equality
8056
8057 Eq_Prim := Empty;
8058
8059 -- Inspect the list of primitives looking for a suitable equality
8060 -- within a possible chain of aliases.
8061
8062 Prim_Elmt := First_Elmt (Prims);
8063 while Present (Prim_Elmt) and then No (Eq_Prim) loop
8064 Eq_Prim := Find_Aliased_Equality (Node (Prim_Elmt));
8065
e1a20c09
HK
8066 Next_Elmt (Prim_Elmt);
8067 end loop;
8068
0715a2a8 8069 -- A tagged type should always have an equality
e1a20c09 8070
0715a2a8 8071 pragma Assert (Present (Eq_Prim));
e1a20c09 8072
0715a2a8 8073 return Eq_Prim;
e1a20c09
HK
8074 end Find_Equality;
8075
d7c37f45
SB
8076 ----------------------------------------
8077 -- User_Defined_Primitive_Equality_Op --
8078 ----------------------------------------
8079
8080 function User_Defined_Primitive_Equality_Op
8081 (Typ : Entity_Id) return Entity_Id
8082 is
c3870f3b 8083 Enclosing_Scope : constant Entity_Id := Scope (Typ);
d7c37f45
SB
8084 E : Entity_Id;
8085 begin
d7c37f45
SB
8086 for Private_Entities in Boolean loop
8087 if Private_Entities then
8088 if Ekind (Enclosing_Scope) /= E_Package then
8089 exit;
8090 end if;
8091 E := First_Private_Entity (Enclosing_Scope);
8092
8093 else
8094 E := First_Entity (Enclosing_Scope);
8095 end if;
8096
8097 while Present (E) loop
8098 if Is_Equality (E, Typ) then
8099 return E;
8100 end if;
99859ea7 8101 Next_Entity (E);
d7c37f45
SB
8102 end loop;
8103 end loop;
8104
8105 if Is_Derived_Type (Typ) then
8106 return User_Defined_Primitive_Equality_Op
8107 (Implementation_Base_Type (Etype (Typ)));
8108 end if;
8109
8110 return Empty;
8111 end User_Defined_Primitive_Equality_Op;
8112
5d09245e
AC
8113 ------------------------------------
8114 -- Has_Unconstrained_UU_Component --
8115 ------------------------------------
8116
8117 function Has_Unconstrained_UU_Component
e1a20c09 8118 (Typ : Entity_Id) return Boolean
5d09245e 8119 is
e02f9af5
PT
8120 function Unconstrained_UU_In_Component_Declaration
8121 (N : Node_Id) return Boolean;
8122
8123 function Unconstrained_UU_In_Component_Items
8124 (L : List_Id) return Boolean;
8125
8126 function Unconstrained_UU_In_Component_List
8127 (N : Node_Id) return Boolean;
8128
8129 function Unconstrained_UU_In_Variant_Part
8130 (N : Node_Id) return Boolean;
8131 -- A family of routines that determine whether a particular construct
8132 -- of a record type definition contains a subcomponent of an
8133 -- unchecked union type whose nominal subtype is unconstrained.
8134 --
8135 -- Individual routines correspond to the production rules of the Ada
8136 -- grammar, as described in the Ada RM (P).
8137
8138 -----------------------------------------------
8139 -- Unconstrained_UU_In_Component_Declaration --
8140 -----------------------------------------------
8141
8142 function Unconstrained_UU_In_Component_Declaration
8143 (N : Node_Id) return Boolean
5d09245e 8144 is
e02f9af5 8145 pragma Assert (Nkind (N) = N_Component_Declaration);
5d09245e 8146
e02f9af5
PT
8147 Sindic : constant Node_Id :=
8148 Subtype_Indication (Component_Definition (N));
8149 begin
476ed6bf
ES
8150 -- If the component declaration includes a subtype indication
8151 -- it is not an unchecked_union. Otherwise verify that it carries
8152 -- the Unchecked_Union flag and is either a record or a private
8153 -- type. A Record_Subtype declared elsewhere does not qualify,
8154 -- even if its parent type carries the flag.
5d09245e 8155
e02f9af5 8156 return Nkind (Sindic) in N_Expanded_Name | N_Identifier
476ed6bf
ES
8157 and then Is_Unchecked_Union (Base_Type (Etype (Sindic)))
8158 and then (Ekind (Entity (Sindic)) in
8159 E_Private_Type | E_Record_Type);
e02f9af5 8160 end Unconstrained_UU_In_Component_Declaration;
5d09245e 8161
e02f9af5
PT
8162 -----------------------------------------
8163 -- Unconstrained_UU_In_Component_Items --
8164 -----------------------------------------
5d09245e 8165
e02f9af5
PT
8166 function Unconstrained_UU_In_Component_Items
8167 (L : List_Id) return Boolean
5d09245e 8168 is
e02f9af5 8169 N : Node_Id := First (L);
5d09245e 8170 begin
e02f9af5
PT
8171 while Present (N) loop
8172 if Nkind (N) = N_Component_Declaration
8173 and then Unconstrained_UU_In_Component_Declaration (N)
8174 then
7faaabcc
PT
8175 return True;
8176 end if;
5d09245e 8177
e02f9af5 8178 Next (N);
7faaabcc 8179 end loop;
5d09245e 8180
5d09245e 8181 return False;
e02f9af5 8182 end Unconstrained_UU_In_Component_Items;
5d09245e 8183
e02f9af5
PT
8184 ----------------------------------------
8185 -- Unconstrained_UU_In_Component_List --
8186 ----------------------------------------
5d09245e 8187
e02f9af5
PT
8188 function Unconstrained_UU_In_Component_List
8189 (N : Node_Id) return Boolean
8190 is
8191 pragma Assert (Nkind (N) = N_Component_List);
5d09245e 8192
e02f9af5
PT
8193 Optional_Variant_Part : Node_Id;
8194 begin
8195 if Unconstrained_UU_In_Component_Items (Component_Items (N)) then
8196 return True;
8197 end if;
5d09245e 8198
e02f9af5 8199 Optional_Variant_Part := Variant_Part (N);
5d09245e 8200
e02f9af5
PT
8201 return
8202 Present (Optional_Variant_Part)
8203 and then
8204 Unconstrained_UU_In_Variant_Part (Optional_Variant_Part);
8205 end Unconstrained_UU_In_Component_List;
5d09245e 8206
e02f9af5
PT
8207 --------------------------------------
8208 -- Unconstrained_UU_In_Variant_Part --
8209 --------------------------------------
5d09245e 8210
e02f9af5
PT
8211 function Unconstrained_UU_In_Variant_Part
8212 (N : Node_Id) return Boolean
8213 is
8214 pragma Assert (Nkind (N) = N_Variant_Part);
5d09245e 8215
e02f9af5
PT
8216 Variant : Node_Id := First (Variants (N));
8217 begin
8218 loop
8219 if Unconstrained_UU_In_Component_List (Component_List (Variant))
8220 then
8221 return True;
8222 end if;
5d09245e 8223
e02f9af5
PT
8224 Next (Variant);
8225 exit when No (Variant);
8226 end loop;
5d09245e 8227
e02f9af5
PT
8228 return False;
8229 end Unconstrained_UU_In_Variant_Part;
5d09245e 8230
e02f9af5
PT
8231 Typ_Def : constant Node_Id :=
8232 Type_Definition (Declaration_Node (Base_Type (Typ)));
5d09245e 8233
e02f9af5
PT
8234 Optional_Component_List : constant Node_Id :=
8235 Component_List (Typ_Def);
5d09245e 8236
e02f9af5 8237 -- Start of processing for Has_Unconstrained_UU_Component
5d09245e 8238
e02f9af5
PT
8239 begin
8240 return Present (Optional_Component_List)
8241 and then
8242 Unconstrained_UU_In_Component_List (Optional_Component_List);
5d09245e
AC
8243 end Has_Unconstrained_UU_Component;
8244
e1a20c09
HK
8245 -- Local variables
8246
8247 Typl : Entity_Id;
8248
70482933
RK
8249 -- Start of processing for Expand_N_Op_Eq
8250
8251 begin
8252 Binary_Op_Validity_Checks (N);
8253
456cbfa5
AC
8254 -- Deal with private types
8255
e1a20c09
HK
8256 Typl := A_Typ;
8257
70482933
RK
8258 if Ekind (Typl) = E_Private_Type then
8259 Typl := Underlying_Type (Typl);
e1a20c09 8260
70482933
RK
8261 elsif Ekind (Typl) = E_Private_Subtype then
8262 Typl := Underlying_Type (Base_Type (Typl));
8263 end if;
8264
8265 -- It may happen in error situations that the underlying type is not
8266 -- set. The error will be detected later, here we just defend the
8267 -- expander code.
8268
8269 if No (Typl) then
8270 return;
8271 end if;
8272
a92230c5
AC
8273 -- Now get the implementation base type (note that plain Base_Type here
8274 -- might lead us back to the private type, which is not what we want!)
8275
8276 Typl := Implementation_Base_Type (Typl);
70482933 8277
dda38714
AC
8278 -- Equality between variant records results in a call to a routine
8279 -- that has conditional tests of the discriminant value(s), and hence
8280 -- violates the No_Implicit_Conditionals restriction.
8281
8282 if Has_Variant_Part (Typl) then
8283 declare
8284 Msg : Boolean;
8285
8286 begin
8287 Check_Restriction (Msg, No_Implicit_Conditionals, N);
8288
8289 if Msg then
8290 Error_Msg_N
8291 ("\comparison of variant records tests discriminants", N);
8292 return;
8293 end if;
8294 end;
8295 end if;
8296
456cbfa5 8297 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 8298 -- means we no longer have a comparison operation, we are all done.
456cbfa5 8299
b55ef4b8
EB
8300 if Minimized_Eliminated_Overflow_Check (Left_Opnd (N)) then
8301 Expand_Compare_Minimize_Eliminate_Overflow (N);
8302 end if;
456cbfa5
AC
8303
8304 if Nkind (N) /= N_Op_Eq then
8305 return;
8306 end if;
8307
70482933
RK
8308 -- Boolean types (requiring handling of non-standard case)
8309
f02b8bb8 8310 if Is_Boolean_Type (Typl) then
70482933
RK
8311 Adjust_Condition (Left_Opnd (N));
8312 Adjust_Condition (Right_Opnd (N));
8313 Set_Etype (N, Standard_Boolean);
8314 Adjust_Result_Type (N, Typ);
8315
8316 -- Array types
8317
8318 elsif Is_Array_Type (Typl) then
8319
1033834f
RD
8320 -- If we are doing full validity checking, and it is possible for the
8321 -- array elements to be invalid then expand out array comparisons to
8322 -- make sure that we check the array elements.
fbf5a39b 8323
1033834f
RD
8324 if Validity_Check_Operands
8325 and then not Is_Known_Valid (Component_Type (Typl))
8326 then
fbf5a39b
AC
8327 declare
8328 Save_Force_Validity_Checks : constant Boolean :=
8329 Force_Validity_Checks;
8330 begin
8331 Force_Validity_Checks := True;
8332 Rewrite (N,
0da2c8ac
AC
8333 Expand_Array_Equality
8334 (N,
8335 Relocate_Node (Lhs),
8336 Relocate_Node (Rhs),
8337 Bodies,
8338 Typl));
8339 Insert_Actions (N, Bodies);
fbf5a39b
AC
8340 Analyze_And_Resolve (N, Standard_Boolean);
8341 Force_Validity_Checks := Save_Force_Validity_Checks;
8342 end;
8343
a9d8907c 8344 -- Packed case where both operands are known aligned
70482933 8345
a9d8907c
JM
8346 elsif Is_Bit_Packed_Array (Typl)
8347 and then not Is_Possibly_Unaligned_Object (Lhs)
8348 and then not Is_Possibly_Unaligned_Object (Rhs)
8349 then
70482933
RK
8350 Expand_Packed_Eq (N);
8351
5e1c00fa
RD
8352 -- Where the component type is elementary we can use a block bit
8353 -- comparison (if supported on the target) exception in the case
8354 -- of floating-point (negative zero issues require element by
b120ca61 8355 -- element comparison), and full access types (where we must be sure
a9d8907c 8356 -- to load elements independently) and possibly unaligned arrays.
70482933 8357
70482933
RK
8358 elsif Is_Elementary_Type (Component_Type (Typl))
8359 and then not Is_Floating_Point_Type (Component_Type (Typl))
b120ca61 8360 and then not Is_Full_Access (Component_Type (Typl))
a9d8907c 8361 and then not Is_Possibly_Unaligned_Object (Lhs)
00907026 8362 and then not Is_Possibly_Unaligned_Slice (Lhs)
a9d8907c 8363 and then not Is_Possibly_Unaligned_Object (Rhs)
00907026 8364 and then not Is_Possibly_Unaligned_Slice (Rhs)
fbf5a39b 8365 and then Support_Composite_Compare_On_Target
70482933
RK
8366 then
8367 null;
8368
685094bf
RD
8369 -- For composite and floating-point cases, expand equality loop to
8370 -- make sure of using proper comparisons for tagged types, and
8371 -- correctly handling the floating-point case.
70482933
RK
8372
8373 else
8374 Rewrite (N,
0da2c8ac
AC
8375 Expand_Array_Equality
8376 (N,
8377 Relocate_Node (Lhs),
8378 Relocate_Node (Rhs),
8379 Bodies,
8380 Typl));
70482933
RK
8381 Insert_Actions (N, Bodies, Suppress => All_Checks);
8382 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
8383 end if;
8384
8385 -- Record Types
8386
8387 elsif Is_Record_Type (Typl) then
8388
8389 -- For tagged types, use the primitive "="
8390
8391 if Is_Tagged_Type (Typl) then
8392
0669bebe
GB
8393 -- No need to do anything else compiling under restriction
8394 -- No_Dispatching_Calls. During the semantic analysis we
8395 -- already notified such violation.
8396
8397 if Restriction_Active (No_Dispatching_Calls) then
8398 return;
8399 end if;
8400
65641255
JM
8401 -- If this is an untagged private type completed with a derivation
8402 -- of an untagged private type whose full view is a tagged type,
8403 -- we use the primitive operations of the private type (since it
8404 -- does not have a full view, and also because its equality
8405 -- primitive may have been overridden in its untagged full view).
8406
8407 if Inherits_From_Tagged_Full_View (A_Typ) then
e1a20c09
HK
8408 Build_Equality_Call
8409 (Find_Equality (Collect_Primitive_Operations (A_Typ)));
fbf5a39b
AC
8410
8411 -- Find the type's predefined equality or an overriding
3dddb11e 8412 -- user-defined equality. The reason for not simply calling
fbf5a39b 8413 -- Find_Prim_Op here is that there may be a user-defined
3dddb11e
ES
8414 -- overloaded equality op that precedes the equality that we
8415 -- want, so we have to explicitly search (e.g., there could be
8416 -- an equality with two different parameter types).
fbf5a39b 8417
70482933 8418 else
fbf5a39b 8419 if Is_Class_Wide_Type (Typl) then
3dddb11e 8420 Typl := Find_Specific_Type (Typl);
fbf5a39b
AC
8421 end if;
8422
e1a20c09
HK
8423 Build_Equality_Call
8424 (Find_Equality (Primitive_Operations (Typl)));
70482933
RK
8425 end if;
8426
d7c37f45
SB
8427 -- See AI12-0101 (which only removes a legality rule) and then
8428 -- AI05-0123 (which then applies in the previously illegal case).
8429 -- AI12-0101 is a binding interpretation.
8430
8431 elsif Ada_Version >= Ada_2012
8432 and then Present (User_Defined_Primitive_Equality_Op (Typl))
8433 then
8434 Build_Equality_Call (User_Defined_Primitive_Equality_Op (Typl));
8435
5d09245e
AC
8436 -- Ada 2005 (AI-216): Program_Error is raised when evaluating the
8437 -- predefined equality operator for a type which has a subcomponent
8438 -- of an Unchecked_Union type whose nominal subtype is unconstrained.
8439
8440 elsif Has_Unconstrained_UU_Component (Typl) then
8441 Insert_Action (N,
8442 Make_Raise_Program_Error (Loc,
8443 Reason => PE_Unchecked_Union_Restriction));
8444
8445 -- Prevent Gigi from generating incorrect code by rewriting the
6cb3037c 8446 -- equality as a standard False. (is this documented somewhere???)
5d09245e
AC
8447
8448 Rewrite (N,
8449 New_Occurrence_Of (Standard_False, Loc));
8450
8451 elsif Is_Unchecked_Union (Typl) then
8452
8453 -- If we can infer the discriminants of the operands, we make a
8454 -- call to the TSS equality function.
8455
8456 if Has_Inferable_Discriminants (Lhs)
8457 and then
8458 Has_Inferable_Discriminants (Rhs)
8459 then
8460 Build_Equality_Call
8461 (TSS (Root_Type (Typl), TSS_Composite_Equality));
8462
8463 else
8464 -- Ada 2005 (AI-216): Program_Error is raised when evaluating
8465 -- the predefined equality operator for an Unchecked_Union type
8466 -- if either of the operands lack inferable discriminants.
8467
8468 Insert_Action (N,
8469 Make_Raise_Program_Error (Loc,
8470 Reason => PE_Unchecked_Union_Restriction));
8471
29ad9ea5
AC
8472 -- Emit a warning on source equalities only, otherwise the
8473 -- message may appear out of place due to internal use. The
8474 -- warning is unconditional because it is required by the
8475 -- language.
8476
8477 if Comes_From_Source (N) then
8478 Error_Msg_N
facfa165 8479 ("Unchecked_Union discriminants cannot be determined??",
29ad9ea5
AC
8480 N);
8481 Error_Msg_N
facfa165 8482 ("\Program_Error will be raised for equality operation??",
29ad9ea5
AC
8483 N);
8484 end if;
8485
5d09245e 8486 -- Prevent Gigi from generating incorrect code by rewriting
6cb3037c 8487 -- the equality as a standard False (documented where???).
5d09245e
AC
8488
8489 Rewrite (N,
8490 New_Occurrence_Of (Standard_False, Loc));
5d09245e
AC
8491 end if;
8492
70482933
RK
8493 -- If a type support function is present (for complex cases), use it
8494
fbf5a39b
AC
8495 elsif Present (TSS (Root_Type (Typl), TSS_Composite_Equality)) then
8496 Build_Equality_Call
8497 (TSS (Root_Type (Typl), TSS_Composite_Equality));
70482933 8498
8d80ff64
AC
8499 -- When comparing two Bounded_Strings, use the primitive equality of
8500 -- the root Super_String type.
8501
8502 elsif Is_Bounded_String (Typl) then
e1a20c09
HK
8503 Build_Equality_Call
8504 (Find_Equality
8505 (Collect_Primitive_Operations (Root_Type (Typl))));
8d80ff64 8506
70482933 8507 -- Otherwise expand the component by component equality. Note that
8fc789c8 8508 -- we never use block-bit comparisons for records, because of the
c7a494c9 8509 -- problems with gaps. The back end will often be able to recombine
70482933
RK
8510 -- the separate comparisons that we generate here.
8511
8512 else
8513 Remove_Side_Effects (Lhs);
8514 Remove_Side_Effects (Rhs);
8515 Rewrite (N,
8516 Expand_Record_Equality (N, Typl, Lhs, Rhs, Bodies));
8517
8518 Insert_Actions (N, Bodies, Suppress => All_Checks);
8519 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
8520 end if;
6bc08721
JM
8521
8522 -- If unnesting, handle elementary types whose Equivalent_Types are
8523 -- records because there may be padding or undefined fields.
8524
8525 elsif Unnest_Subprogram_Mode
4a08c95c
AC
8526 and then Ekind (Typl) in E_Class_Wide_Type
8527 | E_Class_Wide_Subtype
8528 | E_Access_Subprogram_Type
8529 | E_Access_Protected_Subprogram_Type
8530 | E_Anonymous_Access_Protected_Subprogram_Type
8531 | E_Exception_Type
6bc08721
JM
8532 and then Present (Equivalent_Type (Typl))
8533 and then Is_Record_Type (Equivalent_Type (Typl))
8534 then
8535 Typl := Equivalent_Type (Typl);
8536 Remove_Side_Effects (Lhs);
8537 Remove_Side_Effects (Rhs);
8538 Rewrite (N,
8539 Expand_Record_Equality (N, Typl,
8540 Unchecked_Convert_To (Typl, Lhs),
8541 Unchecked_Convert_To (Typl, Rhs),
8542 Bodies));
8543
8544 Insert_Actions (N, Bodies, Suppress => All_Checks);
8545 Analyze_And_Resolve (N, Standard_Boolean, Suppress => All_Checks);
70482933
RK
8546 end if;
8547
d26dc4b5 8548 -- Test if result is known at compile time
70482933 8549
d26dc4b5 8550 Rewrite_Comparison (N);
f02b8bb8 8551
6c8e4f7e
EB
8552 -- Try to narrow the operation
8553
8554 if Typl = Universal_Integer and then Nkind (N) = N_Op_Eq then
8555 Narrow_Large_Operation (N);
8556 end if;
8557
878e58c8
RD
8558 -- Special optimization of length comparison
8559
0580d807 8560 Optimize_Length_Comparison (N);
878e58c8 8561
088c7e1b 8562 -- One more special case: if we have a comparison of X'Result = expr
878e58c8 8563 -- in floating-point, then if not already there, change expr to be
088c7e1b 8564 -- f'Machine (expr) to eliminate surprise from extra precision.
878e58c8
RD
8565
8566 if Is_Floating_Point_Type (Typl)
8567 and then Nkind (Original_Node (Lhs)) = N_Attribute_Reference
8568 and then Attribute_Name (Original_Node (Lhs)) = Name_Result
8569 then
8570 -- Stick in the Typ'Machine call if not already there
8571
8572 if Nkind (Rhs) /= N_Attribute_Reference
8573 or else Attribute_Name (Rhs) /= Name_Machine
8574 then
8575 Rewrite (Rhs,
8576 Make_Attribute_Reference (Loc,
8577 Prefix => New_Occurrence_Of (Typl, Loc),
8578 Attribute_Name => Name_Machine,
8579 Expressions => New_List (Relocate_Node (Rhs))));
8580 Analyze_And_Resolve (Rhs, Typl);
8581 end if;
8582 end if;
70482933
RK
8583 end Expand_N_Op_Eq;
8584
8585 -----------------------
8586 -- Expand_N_Op_Expon --
8587 -----------------------
8588
8589 procedure Expand_N_Op_Expon (N : Node_Id) is
0bcee275
AC
8590 Loc : constant Source_Ptr := Sloc (N);
8591 Ovflo : constant Boolean := Do_Overflow_Check (N);
8592 Typ : constant Entity_Id := Etype (N);
8593 Rtyp : constant Entity_Id := Root_Type (Typ);
8594
8595 Bastyp : Entity_Id;
70482933 8596
83496138
AC
8597 function Wrap_MA (Exp : Node_Id) return Node_Id;
8598 -- Given an expression Exp, if the root type is Float or Long_Float,
8599 -- then wrap the expression in a call of Bastyp'Machine, to stop any
8600 -- extra precision. This is done to ensure that X**A = X**B when A is
8601 -- a static constant and B is a variable with the same value. For any
8602 -- other type, the node Exp is returned unchanged.
8603
8604 -------------
8605 -- Wrap_MA --
8606 -------------
8607
8608 function Wrap_MA (Exp : Node_Id) return Node_Id is
8609 Loc : constant Source_Ptr := Sloc (Exp);
0bcee275 8610
83496138
AC
8611 begin
8612 if Rtyp = Standard_Float or else Rtyp = Standard_Long_Float then
8613 return
8614 Make_Attribute_Reference (Loc,
8615 Attribute_Name => Name_Machine,
8616 Prefix => New_Occurrence_Of (Bastyp, Loc),
8617 Expressions => New_List (Relocate_Node (Exp)));
8618 else
8619 return Exp;
8620 end if;
8621 end Wrap_MA;
8622
0bcee275
AC
8623 -- Local variables
8624
8625 Base : Node_Id;
8626 Ent : Entity_Id;
8627 Etyp : Entity_Id;
8628 Exp : Node_Id;
8629 Exptyp : Entity_Id;
8630 Expv : Uint;
8631 Rent : RE_Id;
8632 Temp : Node_Id;
8633 Xnode : Node_Id;
8634
904a2ae4 8635 -- Start of processing for Expand_N_Op_Expon
83496138 8636
70482933
RK
8637 begin
8638 Binary_Op_Validity_Checks (N);
8639
5114f3ff 8640 -- CodePeer wants to see the unexpanded N_Op_Expon node
8f66cda7 8641
5114f3ff 8642 if CodePeer_Mode then
8f66cda7
AC
8643 return;
8644 end if;
8645
904a2ae4
AC
8646 -- Relocation of left and right operands must be done after performing
8647 -- the validity checks since the generation of validation checks may
8648 -- remove side effects.
8649
8650 Base := Relocate_Node (Left_Opnd (N));
8651 Bastyp := Etype (Base);
8652 Exp := Relocate_Node (Right_Opnd (N));
8653 Exptyp := Etype (Exp);
8654
685094bf
RD
8655 -- If either operand is of a private type, then we have the use of an
8656 -- intrinsic operator, and we get rid of the privateness, by using root
8657 -- types of underlying types for the actual operation. Otherwise the
8658 -- private types will cause trouble if we expand multiplications or
8659 -- shifts etc. We also do this transformation if the result type is
8660 -- different from the base type.
07fc65c4
GB
8661
8662 if Is_Private_Type (Etype (Base))
8f66cda7
AC
8663 or else Is_Private_Type (Typ)
8664 or else Is_Private_Type (Exptyp)
8665 or else Rtyp /= Root_Type (Bastyp)
07fc65c4
GB
8666 then
8667 declare
8668 Bt : constant Entity_Id := Root_Type (Underlying_Type (Bastyp));
8669 Et : constant Entity_Id := Root_Type (Underlying_Type (Exptyp));
07fc65c4
GB
8670 begin
8671 Rewrite (N,
8672 Unchecked_Convert_To (Typ,
8673 Make_Op_Expon (Loc,
8674 Left_Opnd => Unchecked_Convert_To (Bt, Base),
8675 Right_Opnd => Unchecked_Convert_To (Et, Exp))));
8676 Analyze_And_Resolve (N, Typ);
8677 return;
8678 end;
8679 end if;
8680
b6b5cca8 8681 -- Check for MINIMIZED/ELIMINATED overflow mode
6cb3037c 8682
b6b5cca8 8683 if Minimized_Eliminated_Overflow_Check (N) then
6cb3037c
AC
8684 Apply_Arithmetic_Overflow_Check (N);
8685 return;
8686 end if;
8687
cb42ba5d
AC
8688 -- Test for case of known right argument where we can replace the
8689 -- exponentiation by an equivalent expression using multiplication.
70482933 8690
6c3c671e
AC
8691 -- Note: use CRT_Safe version of Compile_Time_Known_Value because in
8692 -- configurable run-time mode, we may not have the exponentiation
8693 -- routine available, and we don't want the legality of the program
8694 -- to depend on how clever the compiler is in knowing values.
8695
8696 if CRT_Safe_Compile_Time_Known_Value (Exp) then
70482933
RK
8697 Expv := Expr_Value (Exp);
8698
8699 -- We only fold small non-negative exponents. You might think we
8700 -- could fold small negative exponents for the real case, but we
8701 -- can't because we are required to raise Constraint_Error for
8702 -- the case of 0.0 ** (negative) even if Machine_Overflows = False.
83496138 8703 -- See ACVC test C4A012B, and it is not worth generating the test.
70482933 8704
00f45f30
AC
8705 -- For small negative exponents, we return the reciprocal of
8706 -- the folding of the exponentiation for the opposite (positive)
8707 -- exponent, as required by Ada RM 4.5.6(11/3).
8708
8709 if abs Expv <= 4 then
70482933
RK
8710
8711 -- X ** 0 = 1 (or 1.0)
8712
8713 if Expv = 0 then
abcbd24c
ST
8714
8715 -- Call Remove_Side_Effects to ensure that any side effects
8716 -- in the ignored left operand (in particular function calls
8717 -- to user defined functions) are properly executed.
8718
8719 Remove_Side_Effects (Base);
8720
70482933
RK
8721 if Ekind (Typ) in Integer_Kind then
8722 Xnode := Make_Integer_Literal (Loc, Intval => 1);
8723 else
8724 Xnode := Make_Real_Literal (Loc, Ureal_1);
8725 end if;
8726
8727 -- X ** 1 = X
8728
8729 elsif Expv = 1 then
8730 Xnode := Base;
8731
8732 -- X ** 2 = X * X
8733
8734 elsif Expv = 2 then
8735 Xnode :=
83496138
AC
8736 Wrap_MA (
8737 Make_Op_Multiply (Loc,
8738 Left_Opnd => Duplicate_Subexpr (Base),
8739 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)));
70482933
RK
8740
8741 -- X ** 3 = X * X * X
8742
8743 elsif Expv = 3 then
8744 Xnode :=
83496138
AC
8745 Wrap_MA (
8746 Make_Op_Multiply (Loc,
8747 Left_Opnd =>
8748 Make_Op_Multiply (Loc,
8749 Left_Opnd => Duplicate_Subexpr (Base),
8750 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)),
8751 Right_Opnd => Duplicate_Subexpr_No_Checks (Base)));
70482933
RK
8752
8753 -- X ** 4 ->
cb42ba5d
AC
8754
8755 -- do
70482933 8756 -- En : constant base'type := base * base;
cb42ba5d 8757 -- in
70482933
RK
8758 -- En * En
8759
00f45f30 8760 elsif Expv = 4 then
191fcb3a 8761 Temp := Make_Temporary (Loc, 'E', Base);
70482933 8762
cb42ba5d
AC
8763 Xnode :=
8764 Make_Expression_With_Actions (Loc,
8765 Actions => New_List (
8766 Make_Object_Declaration (Loc,
8767 Defining_Identifier => Temp,
8768 Constant_Present => True,
e4494292 8769 Object_Definition => New_Occurrence_Of (Typ, Loc),
cb42ba5d 8770 Expression =>
83496138
AC
8771 Wrap_MA (
8772 Make_Op_Multiply (Loc,
8773 Left_Opnd =>
8774 Duplicate_Subexpr (Base),
8775 Right_Opnd =>
8776 Duplicate_Subexpr_No_Checks (Base))))),
cb42ba5d 8777
70482933 8778 Expression =>
83496138
AC
8779 Wrap_MA (
8780 Make_Op_Multiply (Loc,
8781 Left_Opnd => New_Occurrence_Of (Temp, Loc),
8782 Right_Opnd => New_Occurrence_Of (Temp, Loc))));
00f45f30
AC
8783
8784 -- X ** N = 1.0 / X ** (-N)
8785 -- N in -4 .. -1
8786
8787 else
8788 pragma Assert
8789 (Expv = -1 or Expv = -2 or Expv = -3 or Expv = -4);
72cdccfa 8790
00f45f30
AC
8791 Xnode :=
8792 Make_Op_Divide (Loc,
8793 Left_Opnd =>
8794 Make_Float_Literal (Loc,
8795 Radix => Uint_1,
8796 Significand => Uint_1,
8797 Exponent => Uint_0),
8798 Right_Opnd =>
8799 Make_Op_Expon (Loc,
8800 Left_Opnd => Duplicate_Subexpr (Base),
8801 Right_Opnd =>
8802 Make_Integer_Literal (Loc,
8803 Intval => -Expv)));
70482933
RK
8804 end if;
8805
8806 Rewrite (N, Xnode);
8807 Analyze_And_Resolve (N, Typ);
8808 return;
8809 end if;
8810 end if;
8811
b502ba3c 8812 -- Deal with optimizing 2 ** expression to shift where possible
685094bf 8813
8b4230c8
AC
8814 -- Note: we used to check that Exptyp was an unsigned type. But that is
8815 -- an unnecessary check, since if Exp is negative, we have a run-time
8816 -- error that is either caught (so we get the right result) or we have
8817 -- suppressed the check, in which case the code is erroneous anyway.
8818
b502ba3c
RD
8819 if Is_Integer_Type (Rtyp)
8820
c2b2b2d7 8821 -- The base value must be "safe compile-time known", and exactly 2
b502ba3c
RD
8822
8823 and then Nkind (Base) = N_Integer_Literal
6c3c671e
AC
8824 and then CRT_Safe_Compile_Time_Known_Value (Base)
8825 and then Expr_Value (Base) = Uint_2
b502ba3c
RD
8826
8827 -- We only handle cases where the right type is a integer
8828
70482933 8829 and then Is_Integer_Type (Root_Type (Exptyp))
cbe3b8d4 8830 and then Esize (Root_Type (Exptyp)) <= Standard_Integer_Size
b502ba3c
RD
8831
8832 -- This transformation is not applicable for a modular type with a
a95f708e 8833 -- nonbinary modulus because we do not handle modular reduction in
b502ba3c
RD
8834 -- a correct manner if we attempt this transformation in this case.
8835
8836 and then not Non_Binary_Modulus (Typ)
70482933 8837 then
b502ba3c
RD
8838 -- Handle the cases where our parent is a division or multiplication
8839 -- specially. In these cases we can convert to using a shift at the
8840 -- parent level if we are not doing overflow checking, since it is
8841 -- too tricky to combine the overflow check at the parent level.
70482933 8842
b502ba3c 8843 if not Ovflo
4a08c95c 8844 and then Nkind (Parent (N)) in N_Op_Divide | N_Op_Multiply
b502ba3c 8845 then
51bf9bdf
AC
8846 declare
8847 P : constant Node_Id := Parent (N);
8848 L : constant Node_Id := Left_Opnd (P);
8849 R : constant Node_Id := Right_Opnd (P);
8850
8851 begin
8852 if (Nkind (P) = N_Op_Multiply
eb9008b7
AC
8853 and then
8854 ((Is_Integer_Type (Etype (L)) and then R = N)
8855 or else
8856 (Is_Integer_Type (Etype (R)) and then L = N))
8857 and then not Do_Overflow_Check (P))
8858
51bf9bdf
AC
8859 or else
8860 (Nkind (P) = N_Op_Divide
533369aa
AC
8861 and then Is_Integer_Type (Etype (L))
8862 and then Is_Unsigned_Type (Etype (L))
8863 and then R = N
8864 and then not Do_Overflow_Check (P))
51bf9bdf
AC
8865 then
8866 Set_Is_Power_Of_2_For_Shift (N);
8867 return;
8868 end if;
8869 end;
8870
b502ba3c
RD
8871 -- Here we just have 2 ** N on its own, so we can convert this to a
8872 -- shift node. We are prepared to deal with overflow here, and we
8873 -- also have to handle proper modular reduction for binary modular.
51bf9bdf 8874
b502ba3c
RD
8875 else
8876 declare
8877 OK : Boolean;
8878 Lo : Uint;
8879 Hi : Uint;
8880
8881 MaxS : Uint;
8882 -- Maximum shift count with no overflow
8883
8884 TestS : Boolean;
8885 -- Set True if we must test the shift count
8886
5389e4ae
RD
8887 Test_Gt : Node_Id;
8888 -- Node for test against TestS
8889
b502ba3c
RD
8890 begin
8891 -- Compute maximum shift based on the underlying size. For a
8892 -- modular type this is one less than the size.
8893
8894 if Is_Modular_Integer_Type (Typ) then
8895
8896 -- For modular integer types, this is the size of the value
8897 -- being shifted minus one. Any larger values will cause
8898 -- modular reduction to a result of zero. Note that we do
8899 -- want the RM_Size here (e.g. mod 2 ** 7, we want a result
8900 -- of 6, since 2**7 should be reduced to zero).
8901
8902 MaxS := RM_Size (Rtyp) - 1;
8903
8904 -- For signed integer types, we use the size of the value
8905 -- being shifted minus 2. Larger values cause overflow.
8906
8907 else
8908 MaxS := Esize (Rtyp) - 2;
8909 end if;
8910
8911 -- Determine range to see if it can be larger than MaxS
8912
67b2ed8e 8913 Determine_Range (Exp, OK, Lo, Hi, Assume_Valid => True);
b502ba3c
RD
8914 TestS := (not OK) or else Hi > MaxS;
8915
8916 -- Signed integer case
8917
8918 if Is_Signed_Integer_Type (Typ) then
8919
8920 -- Generate overflow check if overflow is active. Note that
8921 -- we can simply ignore the possibility of overflow if the
8922 -- flag is not set (means that overflow cannot happen or
8923 -- that overflow checks are suppressed).
8924
8925 if Ovflo and TestS then
8926 Insert_Action (N,
8927 Make_Raise_Constraint_Error (Loc,
8928 Condition =>
8929 Make_Op_Gt (Loc,
67b2ed8e 8930 Left_Opnd => Duplicate_Subexpr (Exp),
b502ba3c
RD
8931 Right_Opnd => Make_Integer_Literal (Loc, MaxS)),
8932 Reason => CE_Overflow_Check_Failed));
8933 end if;
8934
8935 -- Now rewrite node as Shift_Left (1, right-operand)
8936
8937 Rewrite (N,
8938 Make_Op_Shift_Left (Loc,
8939 Left_Opnd => Make_Integer_Literal (Loc, Uint_1),
67b2ed8e 8940 Right_Opnd => Exp));
b502ba3c
RD
8941
8942 -- Modular integer case
8943
8944 else pragma Assert (Is_Modular_Integer_Type (Typ));
8945
8946 -- If shift count can be greater than MaxS, we need to wrap
8947 -- the shift in a test that will reduce the result value to
8948 -- zero if this shift count is exceeded.
8949
8950 if TestS then
5389e4ae
RD
8951
8952 -- Note: build node for the comparison first, before we
8953 -- reuse the Right_Opnd, so that we have proper parents
8954 -- in place for the Duplicate_Subexpr call.
8955
8956 Test_Gt :=
8957 Make_Op_Gt (Loc,
67b2ed8e 8958 Left_Opnd => Duplicate_Subexpr (Exp),
5389e4ae
RD
8959 Right_Opnd => Make_Integer_Literal (Loc, MaxS));
8960
b502ba3c
RD
8961 Rewrite (N,
8962 Make_If_Expression (Loc,
8963 Expressions => New_List (
5389e4ae 8964 Test_Gt,
b502ba3c 8965 Make_Integer_Literal (Loc, Uint_0),
b502ba3c
RD
8966 Make_Op_Shift_Left (Loc,
8967 Left_Opnd => Make_Integer_Literal (Loc, Uint_1),
67b2ed8e 8968 Right_Opnd => Exp))));
b502ba3c
RD
8969
8970 -- If we know shift count cannot be greater than MaxS, then
8971 -- it is safe to just rewrite as a shift with no test.
8972
8973 else
8974 Rewrite (N,
8975 Make_Op_Shift_Left (Loc,
8976 Left_Opnd => Make_Integer_Literal (Loc, Uint_1),
67b2ed8e 8977 Right_Opnd => Exp));
b502ba3c
RD
8978 end if;
8979 end if;
8980
8981 Analyze_And_Resolve (N, Typ);
8982 return;
8983 end;
51bf9bdf 8984 end if;
70482933
RK
8985 end if;
8986
07fc65c4
GB
8987 -- Fall through if exponentiation must be done using a runtime routine
8988
07fc65c4 8989 -- First deal with modular case
70482933
RK
8990
8991 if Is_Modular_Integer_Type (Rtyp) then
8992
83496138
AC
8993 -- Nonbinary modular case, we call the special exponentiation
8994 -- routine for the nonbinary case, converting the argument to
8995 -- Long_Long_Integer and passing the modulus value. Then the
8996 -- result is converted back to the base type.
70482933
RK
8997
8998 if Non_Binary_Modulus (Rtyp) then
70482933
RK
8999 Rewrite (N,
9000 Convert_To (Typ,
9001 Make_Function_Call (Loc,
cc6f5d75
AC
9002 Name =>
9003 New_Occurrence_Of (RTE (RE_Exp_Modular), Loc),
70482933 9004 Parameter_Associations => New_List (
e9daba51 9005 Convert_To (RTE (RE_Unsigned), Base),
70482933
RK
9006 Make_Integer_Literal (Loc, Modulus (Rtyp)),
9007 Exp))));
9008
a5476382 9009 -- Binary modular case, in this case, we call one of three routines,
83496138 9010 -- either the unsigned integer case, or the unsigned long long
a5476382
EB
9011 -- integer case, or the unsigned long long long integer case, with a
9012 -- final "and" operation to do the required mod.
70482933
RK
9013
9014 else
a5476382 9015 if Esize (Rtyp) <= Standard_Integer_Size then
70482933 9016 Ent := RTE (RE_Exp_Unsigned);
a5476382 9017 elsif Esize (Rtyp) <= Standard_Long_Long_Integer_Size then
70482933 9018 Ent := RTE (RE_Exp_Long_Long_Unsigned);
a5476382
EB
9019 else
9020 Ent := RTE (RE_Exp_Long_Long_Long_Unsigned);
70482933
RK
9021 end if;
9022
9023 Rewrite (N,
9024 Convert_To (Typ,
9025 Make_Op_And (Loc,
cc6f5d75 9026 Left_Opnd =>
70482933 9027 Make_Function_Call (Loc,
cc6f5d75 9028 Name => New_Occurrence_Of (Ent, Loc),
70482933
RK
9029 Parameter_Associations => New_List (
9030 Convert_To (Etype (First_Formal (Ent)), Base),
9031 Exp)),
9032 Right_Opnd =>
9033 Make_Integer_Literal (Loc, Modulus (Rtyp) - 1))));
9034
9035 end if;
9036
9037 -- Common exit point for modular type case
9038
9039 Analyze_And_Resolve (N, Typ);
9040 return;
9041
a5476382
EB
9042 -- Signed integer cases, using either Integer, Long_Long_Integer or
9043 -- Long_Long_Long_Integer. It is not worth also having routines for
9044 -- Short_[Short_]Integer, since for most machines it would not help,
9045 -- and it would generate more code that might need certification when
9046 -- a certified run time is required.
70482933 9047
fbf5a39b 9048 -- In the integer cases, we have two routines, one for when overflow
dfd99a80
TQ
9049 -- checks are required, and one when they are not required, since there
9050 -- is a real gain in omitting checks on many machines.
70482933 9051
a5476382
EB
9052 elsif Is_Signed_Integer_Type (Rtyp) then
9053 if Esize (Rtyp) <= Standard_Integer_Size then
9054 Etyp := Standard_Integer;
fbf5a39b 9055
a5476382
EB
9056 if Ovflo then
9057 Rent := RE_Exp_Integer;
9058 else
9059 Rent := RE_Exn_Integer;
9060 end if;
70482933 9061
a5476382
EB
9062 elsif Esize (Rtyp) <= Standard_Long_Long_Integer_Size then
9063 Etyp := Standard_Long_Long_Integer;
9064
9065 if Ovflo then
9066 Rent := RE_Exp_Long_Long_Integer;
9067 else
9068 Rent := RE_Exn_Long_Long_Integer;
9069 end if;
70482933 9070
70482933 9071 else
a5476382
EB
9072 Etyp := Standard_Long_Long_Long_Integer;
9073
9074 if Ovflo then
9075 Rent := RE_Exp_Long_Long_Long_Integer;
9076 else
9077 Rent := RE_Exn_Long_Long_Long_Integer;
9078 end if;
70482933 9079 end if;
fbf5a39b 9080
83496138
AC
9081 -- Floating-point cases. We do not need separate routines for the
9082 -- overflow case here, since in the case of floating-point, we generate
9083 -- infinities anyway as a rule (either that or we automatically trap
9084 -- overflow), and if there is an infinity generated and a range check
9085 -- is required, the check will fail anyway.
9086
fbf5a39b
AC
9087 else
9088 pragma Assert (Is_Floating_Point_Type (Rtyp));
83496138 9089
cd4fb718
EB
9090 -- Short_Float and Float are the same type for GNAT
9091
9092 if Rtyp = Standard_Short_Float or else Rtyp = Standard_Float then
83496138
AC
9093 Etyp := Standard_Float;
9094 Rent := RE_Exn_Float;
9095
9096 elsif Rtyp = Standard_Long_Float then
9097 Etyp := Standard_Long_Float;
9098 Rent := RE_Exn_Long_Float;
9099
9100 else
9101 Etyp := Standard_Long_Long_Float;
9102 Rent := RE_Exn_Long_Long_Float;
9103 end if;
70482933
RK
9104 end if;
9105
9106 -- Common processing for integer cases and floating-point cases.
fbf5a39b 9107 -- If we are in the right type, we can call runtime routine directly
70482933 9108
fbf5a39b 9109 if Typ = Etyp
785d39ac 9110 and then not Is_Universal_Numeric_Type (Rtyp)
70482933
RK
9111 then
9112 Rewrite (N,
83496138
AC
9113 Wrap_MA (
9114 Make_Function_Call (Loc,
9115 Name => New_Occurrence_Of (RTE (Rent), Loc),
9116 Parameter_Associations => New_List (Base, Exp))));
70482933
RK
9117
9118 -- Otherwise we have to introduce conversions (conversions are also
fbf5a39b 9119 -- required in the universal cases, since the runtime routine is
1147c704 9120 -- typed using one of the standard types).
70482933
RK
9121
9122 else
9123 Rewrite (N,
9124 Convert_To (Typ,
9125 Make_Function_Call (Loc,
e4494292 9126 Name => New_Occurrence_Of (RTE (Rent), Loc),
70482933 9127 Parameter_Associations => New_List (
fbf5a39b 9128 Convert_To (Etyp, Base),
70482933
RK
9129 Exp))));
9130 end if;
9131
9132 Analyze_And_Resolve (N, Typ);
9133 return;
9134
fbf5a39b
AC
9135 exception
9136 when RE_Not_Available =>
9137 return;
70482933
RK
9138 end Expand_N_Op_Expon;
9139
9140 --------------------
9141 -- Expand_N_Op_Ge --
9142 --------------------
9143
9144 procedure Expand_N_Op_Ge (N : Node_Id) is
9145 Typ : constant Entity_Id := Etype (N);
9146 Op1 : constant Node_Id := Left_Opnd (N);
9147 Op2 : constant Node_Id := Right_Opnd (N);
9148 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
9149
9150 begin
9151 Binary_Op_Validity_Checks (N);
9152
456cbfa5 9153 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 9154 -- means we no longer have a comparison operation, we are all done.
456cbfa5 9155
b55ef4b8
EB
9156 if Minimized_Eliminated_Overflow_Check (Op1) then
9157 Expand_Compare_Minimize_Eliminate_Overflow (N);
9158 end if;
456cbfa5
AC
9159
9160 if Nkind (N) /= N_Op_Ge then
9161 return;
9162 end if;
9163
9164 -- Array type case
9165
f02b8bb8 9166 if Is_Array_Type (Typ1) then
70482933
RK
9167 Expand_Array_Comparison (N);
9168 return;
9169 end if;
9170
456cbfa5
AC
9171 -- Deal with boolean operands
9172
70482933
RK
9173 if Is_Boolean_Type (Typ1) then
9174 Adjust_Condition (Op1);
9175 Adjust_Condition (Op2);
9176 Set_Etype (N, Standard_Boolean);
9177 Adjust_Result_Type (N, Typ);
9178 end if;
9179
9180 Rewrite_Comparison (N);
f02b8bb8 9181
6c8e4f7e
EB
9182 -- Try to narrow the operation
9183
9184 if Typ1 = Universal_Integer and then Nkind (N) = N_Op_Ge then
9185 Narrow_Large_Operation (N);
9186 end if;
9187
0580d807 9188 Optimize_Length_Comparison (N);
70482933
RK
9189 end Expand_N_Op_Ge;
9190
9191 --------------------
9192 -- Expand_N_Op_Gt --
9193 --------------------
9194
9195 procedure Expand_N_Op_Gt (N : Node_Id) is
9196 Typ : constant Entity_Id := Etype (N);
9197 Op1 : constant Node_Id := Left_Opnd (N);
9198 Op2 : constant Node_Id := Right_Opnd (N);
9199 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
9200
9201 begin
9202 Binary_Op_Validity_Checks (N);
9203
456cbfa5 9204 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 9205 -- means we no longer have a comparison operation, we are all done.
456cbfa5 9206
b55ef4b8
EB
9207 if Minimized_Eliminated_Overflow_Check (Op1) then
9208 Expand_Compare_Minimize_Eliminate_Overflow (N);
9209 end if;
456cbfa5
AC
9210
9211 if Nkind (N) /= N_Op_Gt then
9212 return;
9213 end if;
9214
9215 -- Deal with array type operands
9216
f02b8bb8 9217 if Is_Array_Type (Typ1) then
70482933
RK
9218 Expand_Array_Comparison (N);
9219 return;
9220 end if;
9221
456cbfa5
AC
9222 -- Deal with boolean type operands
9223
70482933
RK
9224 if Is_Boolean_Type (Typ1) then
9225 Adjust_Condition (Op1);
9226 Adjust_Condition (Op2);
9227 Set_Etype (N, Standard_Boolean);
9228 Adjust_Result_Type (N, Typ);
9229 end if;
9230
9231 Rewrite_Comparison (N);
f02b8bb8 9232
6c8e4f7e
EB
9233 -- Try to narrow the operation
9234
9235 if Typ1 = Universal_Integer and then Nkind (N) = N_Op_Gt then
9236 Narrow_Large_Operation (N);
9237 end if;
9238
0580d807 9239 Optimize_Length_Comparison (N);
70482933
RK
9240 end Expand_N_Op_Gt;
9241
9242 --------------------
9243 -- Expand_N_Op_Le --
9244 --------------------
9245
9246 procedure Expand_N_Op_Le (N : Node_Id) is
9247 Typ : constant Entity_Id := Etype (N);
9248 Op1 : constant Node_Id := Left_Opnd (N);
9249 Op2 : constant Node_Id := Right_Opnd (N);
9250 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
9251
9252 begin
9253 Binary_Op_Validity_Checks (N);
9254
456cbfa5 9255 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 9256 -- means we no longer have a comparison operation, we are all done.
456cbfa5 9257
b55ef4b8
EB
9258 if Minimized_Eliminated_Overflow_Check (Op1) then
9259 Expand_Compare_Minimize_Eliminate_Overflow (N);
9260 end if;
456cbfa5
AC
9261
9262 if Nkind (N) /= N_Op_Le then
9263 return;
9264 end if;
9265
9266 -- Deal with array type operands
9267
f02b8bb8 9268 if Is_Array_Type (Typ1) then
70482933
RK
9269 Expand_Array_Comparison (N);
9270 return;
9271 end if;
9272
456cbfa5
AC
9273 -- Deal with Boolean type operands
9274
70482933
RK
9275 if Is_Boolean_Type (Typ1) then
9276 Adjust_Condition (Op1);
9277 Adjust_Condition (Op2);
9278 Set_Etype (N, Standard_Boolean);
9279 Adjust_Result_Type (N, Typ);
9280 end if;
9281
9282 Rewrite_Comparison (N);
f02b8bb8 9283
6c8e4f7e
EB
9284 -- Try to narrow the operation
9285
9286 if Typ1 = Universal_Integer and then Nkind (N) = N_Op_Le then
9287 Narrow_Large_Operation (N);
9288 end if;
9289
0580d807 9290 Optimize_Length_Comparison (N);
70482933
RK
9291 end Expand_N_Op_Le;
9292
9293 --------------------
9294 -- Expand_N_Op_Lt --
9295 --------------------
9296
9297 procedure Expand_N_Op_Lt (N : Node_Id) is
9298 Typ : constant Entity_Id := Etype (N);
9299 Op1 : constant Node_Id := Left_Opnd (N);
9300 Op2 : constant Node_Id := Right_Opnd (N);
9301 Typ1 : constant Entity_Id := Base_Type (Etype (Op1));
9302
9303 begin
9304 Binary_Op_Validity_Checks (N);
9305
456cbfa5 9306 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
60b68e56 9307 -- means we no longer have a comparison operation, we are all done.
456cbfa5 9308
b55ef4b8
EB
9309 if Minimized_Eliminated_Overflow_Check (Op1) then
9310 Expand_Compare_Minimize_Eliminate_Overflow (N);
9311 end if;
456cbfa5
AC
9312
9313 if Nkind (N) /= N_Op_Lt then
9314 return;
9315 end if;
9316
9317 -- Deal with array type operands
9318
f02b8bb8 9319 if Is_Array_Type (Typ1) then
70482933
RK
9320 Expand_Array_Comparison (N);
9321 return;
9322 end if;
9323
456cbfa5
AC
9324 -- Deal with Boolean type operands
9325
70482933
RK
9326 if Is_Boolean_Type (Typ1) then
9327 Adjust_Condition (Op1);
9328 Adjust_Condition (Op2);
9329 Set_Etype (N, Standard_Boolean);
9330 Adjust_Result_Type (N, Typ);
9331 end if;
9332
9333 Rewrite_Comparison (N);
f02b8bb8 9334
6c8e4f7e
EB
9335 -- Try to narrow the operation
9336
9337 if Typ1 = Universal_Integer and then Nkind (N) = N_Op_Lt then
9338 Narrow_Large_Operation (N);
9339 end if;
9340
0580d807 9341 Optimize_Length_Comparison (N);
70482933
RK
9342 end Expand_N_Op_Lt;
9343
9344 -----------------------
9345 -- Expand_N_Op_Minus --
9346 -----------------------
9347
9348 procedure Expand_N_Op_Minus (N : Node_Id) is
9349 Loc : constant Source_Ptr := Sloc (N);
9350 Typ : constant Entity_Id := Etype (N);
9351
9352 begin
9353 Unary_Op_Validity_Checks (N);
9354
b6b5cca8
AC
9355 -- Check for MINIMIZED/ELIMINATED overflow mode
9356
9357 if Minimized_Eliminated_Overflow_Check (N) then
9358 Apply_Arithmetic_Overflow_Check (N);
9359 return;
9360 end if;
9361
6c8e4f7e
EB
9362 -- Try to narrow the operation
9363
9364 if Typ = Universal_Integer then
9365 Narrow_Large_Operation (N);
9366
9367 if Nkind (N) /= N_Op_Minus then
9368 return;
9369 end if;
9370 end if;
9371
07fc65c4 9372 if not Backend_Overflow_Checks_On_Target
6c8e4f7e 9373 and then Is_Signed_Integer_Type (Typ)
70482933
RK
9374 and then Do_Overflow_Check (N)
9375 then
9376 -- Software overflow checking expands -expr into (0 - expr)
9377
9378 Rewrite (N,
9379 Make_Op_Subtract (Loc,
9380 Left_Opnd => Make_Integer_Literal (Loc, 0),
9381 Right_Opnd => Right_Opnd (N)));
9382
9383 Analyze_And_Resolve (N, Typ);
70482933 9384 end if;
05dbb83f 9385
f4ac86dd 9386 Expand_Nonbinary_Modular_Op (N);
70482933
RK
9387 end Expand_N_Op_Minus;
9388
9389 ---------------------
9390 -- Expand_N_Op_Mod --
9391 ---------------------
9392
9393 procedure Expand_N_Op_Mod (N : Node_Id) is
9394 Loc : constant Source_Ptr := Sloc (N);
fbf5a39b 9395 Typ : constant Entity_Id := Etype (N);
70482933
RK
9396 DDC : constant Boolean := Do_Division_Check (N);
9397
b6b5cca8
AC
9398 Left : Node_Id;
9399 Right : Node_Id;
9400
70482933
RK
9401 LLB : Uint;
9402 Llo : Uint;
9403 Lhi : Uint;
9404 LOK : Boolean;
9405 Rlo : Uint;
9406 Rhi : Uint;
9407 ROK : Boolean;
9408
1033834f
RD
9409 pragma Warnings (Off, Lhi);
9410
70482933
RK
9411 begin
9412 Binary_Op_Validity_Checks (N);
9413
b6b5cca8
AC
9414 -- Check for MINIMIZED/ELIMINATED overflow mode
9415
9416 if Minimized_Eliminated_Overflow_Check (N) then
9417 Apply_Arithmetic_Overflow_Check (N);
9418 return;
9419 end if;
9420
6c8e4f7e
EB
9421 -- Try to narrow the operation
9422
9423 if Typ = Universal_Integer then
9424 Narrow_Large_Operation (N);
9425
9426 if Nkind (N) /= N_Op_Mod then
9427 return;
9428 end if;
9429 end if;
9430
9431 if Is_Integer_Type (Typ) then
9a6dc470 9432 Apply_Divide_Checks (N);
b6b5cca8
AC
9433
9434 -- All done if we don't have a MOD any more, which can happen as a
9435 -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
9436
9437 if Nkind (N) /= N_Op_Mod then
9438 return;
9439 end if;
9a6dc470
RD
9440 end if;
9441
b6b5cca8
AC
9442 -- Proceed with expansion of mod operator
9443
9444 Left := Left_Opnd (N);
9445 Right := Right_Opnd (N);
9446
5d5e9775
AC
9447 Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
9448 Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
70482933 9449
2c9f8c0a
AC
9450 -- Convert mod to rem if operands are both known to be non-negative, or
9451 -- both known to be non-positive (these are the cases in which rem and
9452 -- mod are the same, see (RM 4.5.5(28-30)). We do this since it is quite
9453 -- likely that this will improve the quality of code, (the operation now
9454 -- corresponds to the hardware remainder), and it does not seem likely
9455 -- that it could be harmful. It also avoids some cases of the elaborate
9456 -- expansion in Modify_Tree_For_C mode below (since Ada rem = C %).
9457
9458 if (LOK and ROK)
9459 and then ((Llo >= 0 and then Rlo >= 0)
cc6f5d75 9460 or else
2c9f8c0a
AC
9461 (Lhi <= 0 and then Rhi <= 0))
9462 then
70482933
RK
9463 Rewrite (N,
9464 Make_Op_Rem (Sloc (N),
9465 Left_Opnd => Left_Opnd (N),
9466 Right_Opnd => Right_Opnd (N)));
9467
685094bf
RD
9468 -- Instead of reanalyzing the node we do the analysis manually. This
9469 -- avoids anomalies when the replacement is done in an instance and
9470 -- is epsilon more efficient.
70482933
RK
9471
9472 Set_Entity (N, Standard_Entity (S_Op_Rem));
fbf5a39b 9473 Set_Etype (N, Typ);
70482933
RK
9474 Set_Do_Division_Check (N, DDC);
9475 Expand_N_Op_Rem (N);
9476 Set_Analyzed (N);
2c9f8c0a 9477 return;
70482933
RK
9478
9479 -- Otherwise, normal mod processing
9480
9481 else
fbf5a39b 9482 -- Apply optimization x mod 1 = 0. We don't really need that with
f96fd197
AC
9483 -- gcc, but it is useful with other back ends and is certainly
9484 -- harmless.
fbf5a39b
AC
9485
9486 if Is_Integer_Type (Etype (N))
9487 and then Compile_Time_Known_Value (Right)
9488 and then Expr_Value (Right) = Uint_1
9489 then
abcbd24c
ST
9490 -- Call Remove_Side_Effects to ensure that any side effects in
9491 -- the ignored left operand (in particular function calls to
9492 -- user defined functions) are properly executed.
9493
9494 Remove_Side_Effects (Left);
9495
fbf5a39b
AC
9496 Rewrite (N, Make_Integer_Literal (Loc, 0));
9497 Analyze_And_Resolve (N, Typ);
9498 return;
9499 end if;
9500
2c9f8c0a
AC
9501 -- If we still have a mod operator and we are in Modify_Tree_For_C
9502 -- mode, and we have a signed integer type, then here is where we do
9503 -- the rewrite in terms of Rem. Note this rewrite bypasses the need
9504 -- for the special handling of the annoying case of largest negative
9505 -- number mod minus one.
9506
9507 if Nkind (N) = N_Op_Mod
9508 and then Is_Signed_Integer_Type (Typ)
9509 and then Modify_Tree_For_C
9510 then
9511 -- In the general case, we expand A mod B as
9512
9513 -- Tnn : constant typ := A rem B;
9514 -- ..
9515 -- (if (A >= 0) = (B >= 0) then Tnn
9516 -- elsif Tnn = 0 then 0
9517 -- else Tnn + B)
9518
9519 -- The comparison can be written simply as A >= 0 if we know that
9520 -- B >= 0 which is a very common case.
9521
9522 -- An important optimization is when B is known at compile time
9523 -- to be 2**K for some constant. In this case we can simply AND
9524 -- the left operand with the bit string 2**K-1 (i.e. K 1-bits)
9525 -- and that works for both the positive and negative cases.
9526
9527 declare
9528 P2 : constant Nat := Power_Of_Two (Right);
9529
9530 begin
9531 if P2 /= 0 then
9532 Rewrite (N,
9533 Unchecked_Convert_To (Typ,
9534 Make_Op_And (Loc,
9535 Left_Opnd =>
9536 Unchecked_Convert_To
9537 (Corresponding_Unsigned_Type (Typ), Left),
9538 Right_Opnd =>
9539 Make_Integer_Literal (Loc, 2 ** P2 - 1))));
9540 Analyze_And_Resolve (N, Typ);
9541 return;
9542 end if;
9543 end;
9544
9545 -- Here for the full rewrite
9546
9547 declare
9548 Tnn : constant Entity_Id := Make_Temporary (Sloc (N), 'T', N);
9549 Cmp : Node_Id;
9550
9551 begin
9552 Cmp :=
9553 Make_Op_Ge (Loc,
9554 Left_Opnd => Duplicate_Subexpr_No_Checks (Left),
9555 Right_Opnd => Make_Integer_Literal (Loc, 0));
9556
9557 if not LOK or else Rlo < 0 then
9558 Cmp :=
9559 Make_Op_Eq (Loc,
9560 Left_Opnd => Cmp,
9561 Right_Opnd =>
9562 Make_Op_Ge (Loc,
9563 Left_Opnd => Duplicate_Subexpr_No_Checks (Right),
9564 Right_Opnd => Make_Integer_Literal (Loc, 0)));
9565 end if;
9566
9567 Insert_Action (N,
9568 Make_Object_Declaration (Loc,
9569 Defining_Identifier => Tnn,
9570 Constant_Present => True,
9571 Object_Definition => New_Occurrence_Of (Typ, Loc),
9572 Expression =>
9573 Make_Op_Rem (Loc,
9574 Left_Opnd => Left,
9575 Right_Opnd => Right)));
9576
9577 Rewrite (N,
9578 Make_If_Expression (Loc,
9579 Expressions => New_List (
9580 Cmp,
9581 New_Occurrence_Of (Tnn, Loc),
9582 Make_If_Expression (Loc,
9583 Is_Elsif => True,
9584 Expressions => New_List (
9585 Make_Op_Eq (Loc,
9586 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
9587 Right_Opnd => Make_Integer_Literal (Loc, 0)),
9588 Make_Integer_Literal (Loc, 0),
9589 Make_Op_Add (Loc,
9590 Left_Opnd => New_Occurrence_Of (Tnn, Loc),
9591 Right_Opnd =>
9592 Duplicate_Subexpr_No_Checks (Right)))))));
9593
9594 Analyze_And_Resolve (N, Typ);
9595 return;
9596 end;
9597 end if;
9598
9599 -- Deal with annoying case of largest negative number mod minus one.
9600 -- Gigi may not handle this case correctly, because on some targets,
9601 -- the mod value is computed using a divide instruction which gives
9602 -- an overflow trap for this case.
b9daa96e
AC
9603
9604 -- It would be a bit more efficient to figure out which targets
9605 -- this is really needed for, but in practice it is reasonable
9606 -- to do the following special check in all cases, since it means
9607 -- we get a clearer message, and also the overhead is minimal given
9608 -- that division is expensive in any case.
70482933 9609
685094bf
RD
9610 -- In fact the check is quite easy, if the right operand is -1, then
9611 -- the mod value is always 0, and we can just ignore the left operand
9612 -- completely in this case.
70482933 9613
9a6dc470
RD
9614 -- This only applies if we still have a mod operator. Skip if we
9615 -- have already rewritten this (e.g. in the case of eliminated
9616 -- overflow checks which have driven us into bignum mode).
fbf5a39b 9617
9a6dc470 9618 if Nkind (N) = N_Op_Mod then
70482933 9619
9a6dc470
RD
9620 -- The operand type may be private (e.g. in the expansion of an
9621 -- intrinsic operation) so we must use the underlying type to get
9622 -- the bounds, and convert the literals explicitly.
70482933 9623
9a6dc470
RD
9624 LLB :=
9625 Expr_Value
9626 (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
9627
9628 if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
761f7dcb 9629 and then ((not LOK) or else (Llo = LLB))
9a6dc470
RD
9630 then
9631 Rewrite (N,
9b16cb57 9632 Make_If_Expression (Loc,
9a6dc470
RD
9633 Expressions => New_List (
9634 Make_Op_Eq (Loc,
9635 Left_Opnd => Duplicate_Subexpr (Right),
9636 Right_Opnd =>
9637 Unchecked_Convert_To (Typ,
9638 Make_Integer_Literal (Loc, -1))),
9639 Unchecked_Convert_To (Typ,
9640 Make_Integer_Literal (Loc, Uint_0)),
9641 Relocate_Node (N))));
9642
9643 Set_Analyzed (Next (Next (First (Expressions (N)))));
9644 Analyze_And_Resolve (N, Typ);
9645 end if;
70482933
RK
9646 end if;
9647 end if;
9648 end Expand_N_Op_Mod;
9649
9650 --------------------------
9651 -- Expand_N_Op_Multiply --
9652 --------------------------
9653
9654 procedure Expand_N_Op_Multiply (N : Node_Id) is
abcbd24c
ST
9655 Loc : constant Source_Ptr := Sloc (N);
9656 Lop : constant Node_Id := Left_Opnd (N);
9657 Rop : constant Node_Id := Right_Opnd (N);
fbf5a39b 9658
abcbd24c 9659 Lp2 : constant Boolean :=
533369aa 9660 Nkind (Lop) = N_Op_Expon and then Is_Power_Of_2_For_Shift (Lop);
abcbd24c 9661 Rp2 : constant Boolean :=
533369aa 9662 Nkind (Rop) = N_Op_Expon and then Is_Power_Of_2_For_Shift (Rop);
fbf5a39b 9663
70482933
RK
9664 Ltyp : constant Entity_Id := Etype (Lop);
9665 Rtyp : constant Entity_Id := Etype (Rop);
9666 Typ : Entity_Id := Etype (N);
9667
9668 begin
9669 Binary_Op_Validity_Checks (N);
9670
b6b5cca8
AC
9671 -- Check for MINIMIZED/ELIMINATED overflow mode
9672
9673 if Minimized_Eliminated_Overflow_Check (N) then
9674 Apply_Arithmetic_Overflow_Check (N);
9675 return;
9676 end if;
9677
70482933
RK
9678 -- Special optimizations for integer types
9679
9680 if Is_Integer_Type (Typ) then
9681
abcbd24c 9682 -- N * 0 = 0 for integer types
70482933 9683
abcbd24c
ST
9684 if Compile_Time_Known_Value (Rop)
9685 and then Expr_Value (Rop) = Uint_0
70482933 9686 then
abcbd24c
ST
9687 -- Call Remove_Side_Effects to ensure that any side effects in
9688 -- the ignored left operand (in particular function calls to
9689 -- user defined functions) are properly executed.
9690
9691 Remove_Side_Effects (Lop);
9692
9693 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
9694 Analyze_And_Resolve (N, Typ);
9695 return;
9696 end if;
9697
9698 -- Similar handling for 0 * N = 0
9699
9700 if Compile_Time_Known_Value (Lop)
9701 and then Expr_Value (Lop) = Uint_0
9702 then
9703 Remove_Side_Effects (Rop);
70482933
RK
9704 Rewrite (N, Make_Integer_Literal (Loc, Uint_0));
9705 Analyze_And_Resolve (N, Typ);
9706 return;
9707 end if;
9708
9709 -- N * 1 = 1 * N = N for integer types
9710
fbf5a39b
AC
9711 -- This optimisation is not done if we are going to
9712 -- rewrite the product 1 * 2 ** N to a shift.
9713
9714 if Compile_Time_Known_Value (Rop)
9715 and then Expr_Value (Rop) = Uint_1
9716 and then not Lp2
70482933 9717 then
fbf5a39b 9718 Rewrite (N, Lop);
70482933
RK
9719 return;
9720
fbf5a39b
AC
9721 elsif Compile_Time_Known_Value (Lop)
9722 and then Expr_Value (Lop) = Uint_1
9723 and then not Rp2
70482933 9724 then
fbf5a39b 9725 Rewrite (N, Rop);
70482933
RK
9726 return;
9727 end if;
9728 end if;
9729
70482933
RK
9730 -- Convert x * 2 ** y to Shift_Left (x, y). Note that the fact that
9731 -- Is_Power_Of_2_For_Shift is set means that we know that our left
9732 -- operand is an integer, as required for this to work.
9733
fbf5a39b
AC
9734 if Rp2 then
9735 if Lp2 then
70482933 9736
fbf5a39b 9737 -- Convert 2 ** A * 2 ** B into 2 ** (A + B)
70482933
RK
9738
9739 Rewrite (N,
9740 Make_Op_Expon (Loc,
9741 Left_Opnd => Make_Integer_Literal (Loc, 2),
9742 Right_Opnd =>
9743 Make_Op_Add (Loc,
9744 Left_Opnd => Right_Opnd (Lop),
9745 Right_Opnd => Right_Opnd (Rop))));
9746 Analyze_And_Resolve (N, Typ);
9747 return;
9748
9749 else
eefe3761
AC
9750 -- If the result is modular, perform the reduction of the result
9751 -- appropriately.
9752
9753 if Is_Modular_Integer_Type (Typ)
9754 and then not Non_Binary_Modulus (Typ)
9755 then
9756 Rewrite (N,
573e5dd6
RD
9757 Make_Op_And (Loc,
9758 Left_Opnd =>
9759 Make_Op_Shift_Left (Loc,
9760 Left_Opnd => Lop,
9761 Right_Opnd =>
9762 Convert_To (Standard_Natural, Right_Opnd (Rop))),
9763 Right_Opnd =>
eefe3761 9764 Make_Integer_Literal (Loc, Modulus (Typ) - 1)));
573e5dd6 9765
eefe3761
AC
9766 else
9767 Rewrite (N,
9768 Make_Op_Shift_Left (Loc,
9769 Left_Opnd => Lop,
9770 Right_Opnd =>
9771 Convert_To (Standard_Natural, Right_Opnd (Rop))));
9772 end if;
9773
70482933
RK
9774 Analyze_And_Resolve (N, Typ);
9775 return;
9776 end if;
9777
9778 -- Same processing for the operands the other way round
9779
fbf5a39b 9780 elsif Lp2 then
eefe3761
AC
9781 if Is_Modular_Integer_Type (Typ)
9782 and then not Non_Binary_Modulus (Typ)
9783 then
9784 Rewrite (N,
573e5dd6
RD
9785 Make_Op_And (Loc,
9786 Left_Opnd =>
9787 Make_Op_Shift_Left (Loc,
9788 Left_Opnd => Rop,
9789 Right_Opnd =>
9790 Convert_To (Standard_Natural, Right_Opnd (Lop))),
9791 Right_Opnd =>
9792 Make_Integer_Literal (Loc, Modulus (Typ) - 1)));
9793
eefe3761
AC
9794 else
9795 Rewrite (N,
9796 Make_Op_Shift_Left (Loc,
9797 Left_Opnd => Rop,
9798 Right_Opnd =>
9799 Convert_To (Standard_Natural, Right_Opnd (Lop))));
9800 end if;
9801
70482933
RK
9802 Analyze_And_Resolve (N, Typ);
9803 return;
9804 end if;
9805
bc1304f6
EB
9806 -- Try to narrow the operation
9807
9808 if Typ = Universal_Integer then
9809 Narrow_Large_Operation (N);
9810
9811 if Nkind (N) /= N_Op_Multiply then
9812 return;
9813 end if;
9814 end if;
9815
70482933
RK
9816 -- Do required fixup of universal fixed operation
9817
9818 if Typ = Universal_Fixed then
9819 Fixup_Universal_Fixed_Operation (N);
9820 Typ := Etype (N);
9821 end if;
9822
9823 -- Multiplications with fixed-point results
9824
9825 if Is_Fixed_Point_Type (Typ) then
9826
fa54f4da 9827 -- Case of fixed * integer => fixed
70482933 9828
fa54f4da
EB
9829 if Is_Integer_Type (Rtyp) then
9830 Expand_Multiply_Fixed_By_Integer_Giving_Fixed (N);
70482933 9831
fa54f4da 9832 -- Case of integer * fixed => fixed
70482933 9833
fa54f4da
EB
9834 elsif Is_Integer_Type (Ltyp) then
9835 Expand_Multiply_Integer_By_Fixed_Giving_Fixed (N);
70482933 9836
fa54f4da 9837 -- Case of fixed * fixed => fixed
70482933 9838
fa54f4da
EB
9839 else
9840 Expand_Multiply_Fixed_By_Fixed_Giving_Fixed (N);
70482933
RK
9841 end if;
9842
fa54f4da 9843 -- Other cases of multiplication of fixed-point operands
70482933 9844
fa54f4da 9845 elsif Is_Fixed_Point_Type (Ltyp) or else Is_Fixed_Point_Type (Rtyp) then
70482933
RK
9846 if Is_Integer_Type (Typ) then
9847 Expand_Multiply_Fixed_By_Fixed_Giving_Integer (N);
9848 else
9849 pragma Assert (Is_Floating_Point_Type (Typ));
9850 Expand_Multiply_Fixed_By_Fixed_Giving_Float (N);
9851 end if;
9852
685094bf
RD
9853 -- Mixed-mode operations can appear in a non-static universal context,
9854 -- in which case the integer argument must be converted explicitly.
70482933 9855
533369aa 9856 elsif Typ = Universal_Real and then Is_Integer_Type (Rtyp) then
70482933 9857 Rewrite (Rop, Convert_To (Universal_Real, Relocate_Node (Rop)));
70482933
RK
9858 Analyze_And_Resolve (Rop, Universal_Real);
9859
533369aa 9860 elsif Typ = Universal_Real and then Is_Integer_Type (Ltyp) then
70482933 9861 Rewrite (Lop, Convert_To (Universal_Real, Relocate_Node (Lop)));
70482933
RK
9862 Analyze_And_Resolve (Lop, Universal_Real);
9863
9864 -- Non-fixed point cases, check software overflow checking required
9865
9866 elsif Is_Signed_Integer_Type (Etype (N)) then
9867 Apply_Arithmetic_Overflow_Check (N);
9868 end if;
dfaff97b
RD
9869
9870 -- Overflow checks for floating-point if -gnateF mode active
9871
9872 Check_Float_Op_Overflow (N);
05dbb83f 9873
f4ac86dd 9874 Expand_Nonbinary_Modular_Op (N);
70482933
RK
9875 end Expand_N_Op_Multiply;
9876
9877 --------------------
9878 -- Expand_N_Op_Ne --
9879 --------------------
9880
70482933 9881 procedure Expand_N_Op_Ne (N : Node_Id) is
f02b8bb8 9882 Typ : constant Entity_Id := Etype (Left_Opnd (N));
70482933
RK
9883
9884 begin
60f66f34
GD
9885 -- Case of elementary type with standard operator. But if unnesting,
9886 -- handle elementary types whose Equivalent_Types are records because
9887 -- there may be padding or undefined fields.
70482933 9888
f02b8bb8
RD
9889 if Is_Elementary_Type (Typ)
9890 and then Sloc (Entity (N)) = Standard_Location
4a08c95c
AC
9891 and then not (Ekind (Typ) in E_Class_Wide_Type
9892 | E_Class_Wide_Subtype
9893 | E_Access_Subprogram_Type
9894 | E_Access_Protected_Subprogram_Type
9895 | E_Anonymous_Access_Protected_Subprogram_Type
9896 | E_Exception_Type
6bc08721
JM
9897 and then Present (Equivalent_Type (Typ))
9898 and then Is_Record_Type (Equivalent_Type (Typ)))
f02b8bb8
RD
9899 then
9900 Binary_Op_Validity_Checks (N);
70482933 9901
456cbfa5 9902 -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if
60b68e56 9903 -- means we no longer have a /= operation, we are all done.
456cbfa5 9904
b55ef4b8
EB
9905 if Minimized_Eliminated_Overflow_Check (Left_Opnd (N)) then
9906 Expand_Compare_Minimize_Eliminate_Overflow (N);
9907 end if;
456cbfa5
AC
9908
9909 if Nkind (N) /= N_Op_Ne then
9910 return;
9911 end if;
9912
f02b8bb8 9913 -- Boolean types (requiring handling of non-standard case)
70482933 9914
f02b8bb8
RD
9915 if Is_Boolean_Type (Typ) then
9916 Adjust_Condition (Left_Opnd (N));
9917 Adjust_Condition (Right_Opnd (N));
9918 Set_Etype (N, Standard_Boolean);
9919 Adjust_Result_Type (N, Typ);
9920 end if;
fbf5a39b 9921
f02b8bb8
RD
9922 Rewrite_Comparison (N);
9923
6c8e4f7e
EB
9924 -- Try to narrow the operation
9925
9926 if Typ = Universal_Integer and then Nkind (N) = N_Op_Ne then
9927 Narrow_Large_Operation (N);
9928 end if;
9929
f02b8bb8
RD
9930 -- For all cases other than elementary types, we rewrite node as the
9931 -- negation of an equality operation, and reanalyze. The equality to be
9932 -- used is defined in the same scope and has the same signature. This
9933 -- signature must be set explicitly since in an instance it may not have
9934 -- the same visibility as in the generic unit. This avoids duplicating
9935 -- or factoring the complex code for record/array equality tests etc.
9936
99bba92c
AC
9937 -- This case is also used for the minimal expansion performed in
9938 -- GNATprove mode.
9939
f02b8bb8
RD
9940 else
9941 declare
9942 Loc : constant Source_Ptr := Sloc (N);
9943 Neg : Node_Id;
9944 Ne : constant Entity_Id := Entity (N);
9945
9946 begin
9947 Binary_Op_Validity_Checks (N);
9948
9949 Neg :=
9950 Make_Op_Not (Loc,
9951 Right_Opnd =>
9952 Make_Op_Eq (Loc,
9953 Left_Opnd => Left_Opnd (N),
9954 Right_Opnd => Right_Opnd (N)));
99bba92c
AC
9955
9956 -- The level of parentheses is useless in GNATprove mode, and
9957 -- bumping its level here leads to wrong columns being used in
9958 -- check messages, hence skip it in this mode.
9959
9960 if not GNATprove_Mode then
9961 Set_Paren_Count (Right_Opnd (Neg), 1);
9962 end if;
f02b8bb8
RD
9963
9964 if Scope (Ne) /= Standard_Standard then
9965 Set_Entity (Right_Opnd (Neg), Corresponding_Equality (Ne));
9966 end if;
9967
4637729f 9968 -- For navigation purposes, we want to treat the inequality as an
f02b8bb8 9969 -- implicit reference to the corresponding equality. Preserve the
4637729f 9970 -- Comes_From_ source flag to generate proper Xref entries.
f02b8bb8
RD
9971
9972 Preserve_Comes_From_Source (Neg, N);
9973 Preserve_Comes_From_Source (Right_Opnd (Neg), N);
9974 Rewrite (N, Neg);
9975 Analyze_And_Resolve (N, Standard_Boolean);
9976 end;
9977 end if;
0580d807 9978
99bba92c
AC
9979 -- No need for optimization in GNATprove mode, where we would rather see
9980 -- the original source expression.
9981
9982 if not GNATprove_Mode then
9983 Optimize_Length_Comparison (N);
9984 end if;
70482933
RK
9985 end Expand_N_Op_Ne;
9986
9987 ---------------------
9988 -- Expand_N_Op_Not --
9989 ---------------------
9990
685094bf 9991 -- If the argument is other than a Boolean array type, there is no special
7a5b62b0
AC
9992 -- expansion required, except for dealing with validity checks, and non-
9993 -- standard boolean representations.
70482933 9994
7a5b62b0
AC
9995 -- For the packed array case, we call the special routine in Exp_Pakd,
9996 -- except that if the component size is greater than one, we use the
9997 -- standard routine generating a gruesome loop (it is so peculiar to have
9998 -- packed arrays with non-standard Boolean representations anyway, so it
9999 -- does not matter that we do not handle this case efficiently).
70482933 10000
7a5b62b0
AC
10001 -- For the unpacked array case (and for the special packed case where we
10002 -- have non standard Booleans, as discussed above), we generate and insert
10003 -- into the tree the following function definition:
70482933
RK
10004
10005 -- function Nnnn (A : arr) is
10006 -- B : arr;
10007 -- begin
10008 -- for J in a'range loop
10009 -- B (J) := not A (J);
10010 -- end loop;
10011 -- return B;
10012 -- end Nnnn;
10013
b50706ef
AC
10014 -- or in the case of Transform_Function_Array:
10015
10016 -- procedure Nnnn (A : arr; RESULT : out arr) is
10017 -- begin
10018 -- for J in a'range loop
10019 -- RESULT (J) := not A (J);
10020 -- end loop;
10021 -- end Nnnn;
10022
70482933 10023 -- Here arr is the actual subtype of the parameter (and hence always
b50706ef 10024 -- constrained). Then we replace the not with a call to this subprogram.
70482933
RK
10025
10026 procedure Expand_N_Op_Not (N : Node_Id) is
10027 Loc : constant Source_Ptr := Sloc (N);
b50706ef 10028 Typ : constant Entity_Id := Etype (Right_Opnd (N));
70482933
RK
10029 Opnd : Node_Id;
10030 Arr : Entity_Id;
10031 A : Entity_Id;
10032 B : Entity_Id;
10033 J : Entity_Id;
10034 A_J : Node_Id;
10035 B_J : Node_Id;
10036
10037 Func_Name : Entity_Id;
10038 Loop_Statement : Node_Id;
10039
10040 begin
10041 Unary_Op_Validity_Checks (N);
10042
10043 -- For boolean operand, deal with non-standard booleans
10044
10045 if Is_Boolean_Type (Typ) then
10046 Adjust_Condition (Right_Opnd (N));
10047 Set_Etype (N, Standard_Boolean);
10048 Adjust_Result_Type (N, Typ);
10049 return;
10050 end if;
10051
da94696d 10052 -- Only array types need any other processing
70482933 10053
da94696d 10054 if not Is_Array_Type (Typ) then
70482933
RK
10055 return;
10056 end if;
10057
a9d8907c
JM
10058 -- Case of array operand. If bit packed with a component size of 1,
10059 -- handle it in Exp_Pakd if the operand is known to be aligned.
70482933 10060
a9d8907c
JM
10061 if Is_Bit_Packed_Array (Typ)
10062 and then Component_Size (Typ) = 1
10063 and then not Is_Possibly_Unaligned_Object (Right_Opnd (N))
10064 then
70482933
RK
10065 Expand_Packed_Not (N);
10066 return;
10067 end if;
10068
fbf5a39b
AC
10069 -- Case of array operand which is not bit-packed. If the context is
10070 -- a safe assignment, call in-place operation, If context is a larger
10071 -- boolean expression in the context of a safe assignment, expansion is
10072 -- done by enclosing operation.
70482933
RK
10073
10074 Opnd := Relocate_Node (Right_Opnd (N));
10075 Convert_To_Actual_Subtype (Opnd);
10076 Arr := Etype (Opnd);
10077 Ensure_Defined (Arr, N);
b4592168 10078 Silly_Boolean_Array_Not_Test (N, Arr);
70482933 10079
fbf5a39b
AC
10080 if Nkind (Parent (N)) = N_Assignment_Statement then
10081 if Safe_In_Place_Array_Op (Name (Parent (N)), N, Empty) then
10082 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
10083 return;
10084
5e1c00fa 10085 -- Special case the negation of a binary operation
fbf5a39b 10086
4a08c95c 10087 elsif Nkind (Opnd) in N_Op_And | N_Op_Or | N_Op_Xor
fbf5a39b 10088 and then Safe_In_Place_Array_Op
303b4d58 10089 (Name (Parent (N)), Left_Opnd (Opnd), Right_Opnd (Opnd))
fbf5a39b
AC
10090 then
10091 Build_Boolean_Array_Proc_Call (Parent (N), Opnd, Empty);
10092 return;
10093 end if;
10094
10095 elsif Nkind (Parent (N)) in N_Binary_Op
10096 and then Nkind (Parent (Parent (N))) = N_Assignment_Statement
10097 then
10098 declare
10099 Op1 : constant Node_Id := Left_Opnd (Parent (N));
10100 Op2 : constant Node_Id := Right_Opnd (Parent (N));
10101 Lhs : constant Node_Id := Name (Parent (Parent (N)));
10102
10103 begin
10104 if Safe_In_Place_Array_Op (Lhs, Op1, Op2) then
fbf5a39b 10105
aa9a7dd7
AC
10106 -- (not A) op (not B) can be reduced to a single call
10107
10108 if N = Op1 and then Nkind (Op2) = N_Op_Not then
fbf5a39b
AC
10109 return;
10110
bed8af19
AC
10111 elsif N = Op2 and then Nkind (Op1) = N_Op_Not then
10112 return;
10113
aa9a7dd7 10114 -- A xor (not B) can also be special-cased
fbf5a39b 10115
aa9a7dd7 10116 elsif N = Op2 and then Nkind (Parent (N)) = N_Op_Xor then
fbf5a39b
AC
10117 return;
10118 end if;
10119 end if;
10120 end;
10121 end if;
10122
70482933 10123 A := Make_Defining_Identifier (Loc, Name_uA);
b50706ef
AC
10124
10125 if Transform_Function_Array then
10126 B := Make_Defining_Identifier (Loc, Name_UP_RESULT);
10127 else
10128 B := Make_Defining_Identifier (Loc, Name_uB);
10129 end if;
10130
70482933
RK
10131 J := Make_Defining_Identifier (Loc, Name_uJ);
10132
10133 A_J :=
10134 Make_Indexed_Component (Loc,
e4494292
RD
10135 Prefix => New_Occurrence_Of (A, Loc),
10136 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
10137
10138 B_J :=
10139 Make_Indexed_Component (Loc,
e4494292
RD
10140 Prefix => New_Occurrence_Of (B, Loc),
10141 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
10142
10143 Loop_Statement :=
10144 Make_Implicit_Loop_Statement (N,
10145 Identifier => Empty,
10146
10147 Iteration_Scheme =>
10148 Make_Iteration_Scheme (Loc,
10149 Loop_Parameter_Specification =>
10150 Make_Loop_Parameter_Specification (Loc,
0d901290 10151 Defining_Identifier => J,
70482933
RK
10152 Discrete_Subtype_Definition =>
10153 Make_Attribute_Reference (Loc,
0d901290 10154 Prefix => Make_Identifier (Loc, Chars (A)),
70482933
RK
10155 Attribute_Name => Name_Range))),
10156
10157 Statements => New_List (
10158 Make_Assignment_Statement (Loc,
10159 Name => B_J,
10160 Expression => Make_Op_Not (Loc, A_J))));
10161
191fcb3a 10162 Func_Name := Make_Temporary (Loc, 'N');
70482933
RK
10163 Set_Is_Inlined (Func_Name);
10164
b50706ef
AC
10165 if Transform_Function_Array then
10166 Insert_Action (N,
10167 Make_Subprogram_Body (Loc,
10168 Specification =>
10169 Make_Procedure_Specification (Loc,
10170 Defining_Unit_Name => Func_Name,
10171 Parameter_Specifications => New_List (
10172 Make_Parameter_Specification (Loc,
10173 Defining_Identifier => A,
10174 Parameter_Type => New_Occurrence_Of (Typ, Loc)),
10175 Make_Parameter_Specification (Loc,
10176 Defining_Identifier => B,
10177 Out_Present => True,
10178 Parameter_Type => New_Occurrence_Of (Typ, Loc)))),
10179
10180 Declarations => New_List,
10181
10182 Handled_Statement_Sequence =>
10183 Make_Handled_Sequence_Of_Statements (Loc,
10184 Statements => New_List (Loop_Statement))));
70482933 10185
b50706ef
AC
10186 declare
10187 Temp_Id : constant Entity_Id := Make_Temporary (Loc, 'T');
10188 Call : Node_Id;
10189 Decl : Node_Id;
70482933 10190
b50706ef
AC
10191 begin
10192 -- Generate:
10193 -- Temp : ...;
70482933 10194
b50706ef
AC
10195 Decl :=
10196 Make_Object_Declaration (Loc,
10197 Defining_Identifier => Temp_Id,
10198 Object_Definition => New_Occurrence_Of (Typ, Loc));
10199
10200 -- Generate:
10201 -- Proc_Call (Opnd, Temp);
10202
10203 Call :=
10204 Make_Procedure_Call_Statement (Loc,
10205 Name => New_Occurrence_Of (Func_Name, Loc),
10206 Parameter_Associations =>
10207 New_List (Opnd, New_Occurrence_Of (Temp_Id, Loc)));
10208
10209 Insert_Actions (Parent (N), New_List (Decl, Call));
10210 Rewrite (N, New_Occurrence_Of (Temp_Id, Loc));
10211 end;
10212 else
10213 Insert_Action (N,
10214 Make_Subprogram_Body (Loc,
10215 Specification =>
10216 Make_Function_Specification (Loc,
10217 Defining_Unit_Name => Func_Name,
10218 Parameter_Specifications => New_List (
10219 Make_Parameter_Specification (Loc,
10220 Defining_Identifier => A,
10221 Parameter_Type => New_Occurrence_Of (Typ, Loc))),
10222 Result_Definition => New_Occurrence_Of (Typ, Loc)),
10223
10224 Declarations => New_List (
10225 Make_Object_Declaration (Loc,
10226 Defining_Identifier => B,
10227 Object_Definition => New_Occurrence_Of (Arr, Loc))),
10228
10229 Handled_Statement_Sequence =>
10230 Make_Handled_Sequence_Of_Statements (Loc,
10231 Statements => New_List (
10232 Loop_Statement,
10233 Make_Simple_Return_Statement (Loc,
10234 Expression => Make_Identifier (Loc, Chars (B)))))));
10235
10236 Rewrite (N,
10237 Make_Function_Call (Loc,
10238 Name => New_Occurrence_Of (Func_Name, Loc),
10239 Parameter_Associations => New_List (Opnd)));
10240 end if;
70482933
RK
10241
10242 Analyze_And_Resolve (N, Typ);
10243 end Expand_N_Op_Not;
10244
10245 --------------------
10246 -- Expand_N_Op_Or --
10247 --------------------
10248
10249 procedure Expand_N_Op_Or (N : Node_Id) is
10250 Typ : constant Entity_Id := Etype (N);
10251
10252 begin
10253 Binary_Op_Validity_Checks (N);
10254
10255 if Is_Array_Type (Etype (N)) then
10256 Expand_Boolean_Operator (N);
10257
10258 elsif Is_Boolean_Type (Etype (N)) then
f2d10a02
AC
10259 Adjust_Condition (Left_Opnd (N));
10260 Adjust_Condition (Right_Opnd (N));
10261 Set_Etype (N, Standard_Boolean);
10262 Adjust_Result_Type (N, Typ);
437f8c1e
AC
10263
10264 elsif Is_Intrinsic_Subprogram (Entity (N)) then
10265 Expand_Intrinsic_Call (N, Entity (N));
05dbb83f
AC
10266 end if;
10267
f4ac86dd 10268 Expand_Nonbinary_Modular_Op (N);
70482933
RK
10269 end Expand_N_Op_Or;
10270
10271 ----------------------
10272 -- Expand_N_Op_Plus --
10273 ----------------------
10274
10275 procedure Expand_N_Op_Plus (N : Node_Id) is
6c8e4f7e
EB
10276 Typ : constant Entity_Id := Etype (N);
10277
70482933
RK
10278 begin
10279 Unary_Op_Validity_Checks (N);
b6b5cca8
AC
10280
10281 -- Check for MINIMIZED/ELIMINATED overflow mode
10282
10283 if Minimized_Eliminated_Overflow_Check (N) then
10284 Apply_Arithmetic_Overflow_Check (N);
10285 return;
10286 end if;
6c8e4f7e
EB
10287
10288 -- Try to narrow the operation
10289
10290 if Typ = Universal_Integer then
10291 Narrow_Large_Operation (N);
10292 end if;
70482933
RK
10293 end Expand_N_Op_Plus;
10294
10295 ---------------------
10296 -- Expand_N_Op_Rem --
10297 ---------------------
10298
10299 procedure Expand_N_Op_Rem (N : Node_Id) is
10300 Loc : constant Source_Ptr := Sloc (N);
fbf5a39b 10301 Typ : constant Entity_Id := Etype (N);
70482933 10302
b6b5cca8
AC
10303 Left : Node_Id;
10304 Right : Node_Id;
70482933 10305
5d5e9775
AC
10306 Lo : Uint;
10307 Hi : Uint;
10308 OK : Boolean;
70482933 10309
5d5e9775
AC
10310 Lneg : Boolean;
10311 Rneg : Boolean;
10312 -- Set if corresponding operand can be negative
10313
10314 pragma Unreferenced (Hi);
1033834f 10315
70482933
RK
10316 begin
10317 Binary_Op_Validity_Checks (N);
10318
b6b5cca8
AC
10319 -- Check for MINIMIZED/ELIMINATED overflow mode
10320
10321 if Minimized_Eliminated_Overflow_Check (N) then
10322 Apply_Arithmetic_Overflow_Check (N);
10323 return;
10324 end if;
10325
6c8e4f7e
EB
10326 -- Try to narrow the operation
10327
10328 if Typ = Universal_Integer then
10329 Narrow_Large_Operation (N);
10330
10331 if Nkind (N) /= N_Op_Rem then
10332 return;
10333 end if;
10334 end if;
10335
70482933 10336 if Is_Integer_Type (Etype (N)) then
a91e9ac7 10337 Apply_Divide_Checks (N);
b6b5cca8
AC
10338
10339 -- All done if we don't have a REM any more, which can happen as a
10340 -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
10341
10342 if Nkind (N) /= N_Op_Rem then
10343 return;
10344 end if;
70482933
RK
10345 end if;
10346
b6b5cca8
AC
10347 -- Proceed with expansion of REM
10348
10349 Left := Left_Opnd (N);
10350 Right := Right_Opnd (N);
10351
685094bf 10352 -- Apply optimization x rem 1 = 0. We don't really need that with gcc,
f96fd197 10353 -- but it is useful with other back ends, and is certainly harmless.
fbf5a39b
AC
10354
10355 if Is_Integer_Type (Etype (N))
10356 and then Compile_Time_Known_Value (Right)
10357 and then Expr_Value (Right) = Uint_1
10358 then
abcbd24c
ST
10359 -- Call Remove_Side_Effects to ensure that any side effects in the
10360 -- ignored left operand (in particular function calls to user defined
10361 -- functions) are properly executed.
10362
10363 Remove_Side_Effects (Left);
10364
fbf5a39b
AC
10365 Rewrite (N, Make_Integer_Literal (Loc, 0));
10366 Analyze_And_Resolve (N, Typ);
10367 return;
10368 end if;
10369
685094bf 10370 -- Deal with annoying case of largest negative number remainder minus
b9daa96e
AC
10371 -- one. Gigi may not handle this case correctly, because on some
10372 -- targets, the mod value is computed using a divide instruction
10373 -- which gives an overflow trap for this case.
10374
10375 -- It would be a bit more efficient to figure out which targets this
10376 -- is really needed for, but in practice it is reasonable to do the
10377 -- following special check in all cases, since it means we get a clearer
10378 -- message, and also the overhead is minimal given that division is
10379 -- expensive in any case.
70482933 10380
685094bf
RD
10381 -- In fact the check is quite easy, if the right operand is -1, then
10382 -- the remainder is always 0, and we can just ignore the left operand
10383 -- completely in this case.
70482933 10384
5d5e9775
AC
10385 Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
10386 Lneg := (not OK) or else Lo < 0;
fbf5a39b 10387
5d5e9775
AC
10388 Determine_Range (Left, OK, Lo, Hi, Assume_Valid => True);
10389 Rneg := (not OK) or else Lo < 0;
fbf5a39b 10390
5d5e9775
AC
10391 -- We won't mess with trying to find out if the left operand can really
10392 -- be the largest negative number (that's a pain in the case of private
10393 -- types and this is really marginal). We will just assume that we need
10394 -- the test if the left operand can be negative at all.
fbf5a39b 10395
5d5e9775 10396 if Lneg and Rneg then
70482933 10397 Rewrite (N,
9b16cb57 10398 Make_If_Expression (Loc,
70482933
RK
10399 Expressions => New_List (
10400 Make_Op_Eq (Loc,
0d901290 10401 Left_Opnd => Duplicate_Subexpr (Right),
70482933 10402 Right_Opnd =>
0d901290 10403 Unchecked_Convert_To (Typ, Make_Integer_Literal (Loc, -1))),
70482933 10404
fbf5a39b
AC
10405 Unchecked_Convert_To (Typ,
10406 Make_Integer_Literal (Loc, Uint_0)),
70482933
RK
10407
10408 Relocate_Node (N))));
10409
10410 Set_Analyzed (Next (Next (First (Expressions (N)))));
10411 Analyze_And_Resolve (N, Typ);
10412 end if;
10413 end Expand_N_Op_Rem;
10414
10415 -----------------------------
10416 -- Expand_N_Op_Rotate_Left --
10417 -----------------------------
10418
10419 procedure Expand_N_Op_Rotate_Left (N : Node_Id) is
10420 begin
10421 Binary_Op_Validity_Checks (N);
5216b599
AC
10422
10423 -- If we are in Modify_Tree_For_C mode, there is no rotate left in C,
10424 -- so we rewrite in terms of logical shifts
10425
10426 -- Shift_Left (Num, Bits) or Shift_Right (num, Esize - Bits)
10427
10428 -- where Bits is the shift count mod Esize (the mod operation here
10429 -- deals with ludicrous large shift counts, which are apparently OK).
10430
8ad6af8f
AC
10431 if Modify_Tree_For_C then
10432 declare
10433 Loc : constant Source_Ptr := Sloc (N);
10434 Rtp : constant Entity_Id := Etype (Right_Opnd (N));
10435 Typ : constant Entity_Id := Etype (N);
5216b599 10436
8ad6af8f
AC
10437 begin
10438 -- Sem_Intr should prevent getting there with a non binary modulus
10439
10440 pragma Assert (not Non_Binary_Modulus (Typ));
5216b599 10441
5216b599
AC
10442 Rewrite (Right_Opnd (N),
10443 Make_Op_Rem (Loc,
10444 Left_Opnd => Relocate_Node (Right_Opnd (N)),
10445 Right_Opnd => Make_Integer_Literal (Loc, Esize (Typ))));
10446
10447 Analyze_And_Resolve (Right_Opnd (N), Rtp);
10448
10449 Rewrite (N,
10450 Make_Op_Or (Loc,
10451 Left_Opnd =>
10452 Make_Op_Shift_Left (Loc,
10453 Left_Opnd => Left_Opnd (N),
10454 Right_Opnd => Right_Opnd (N)),
e09a5598 10455
5216b599
AC
10456 Right_Opnd =>
10457 Make_Op_Shift_Right (Loc,
10458 Left_Opnd => Duplicate_Subexpr_No_Checks (Left_Opnd (N)),
10459 Right_Opnd =>
10460 Make_Op_Subtract (Loc,
10461 Left_Opnd => Make_Integer_Literal (Loc, Esize (Typ)),
10462 Right_Opnd =>
10463 Duplicate_Subexpr_No_Checks (Right_Opnd (N))))));
10464
10465 Analyze_And_Resolve (N, Typ);
8ad6af8f
AC
10466 end;
10467 end if;
70482933
RK
10468 end Expand_N_Op_Rotate_Left;
10469
10470 ------------------------------
10471 -- Expand_N_Op_Rotate_Right --
10472 ------------------------------
10473
10474 procedure Expand_N_Op_Rotate_Right (N : Node_Id) is
10475 begin
10476 Binary_Op_Validity_Checks (N);
5216b599
AC
10477
10478 -- If we are in Modify_Tree_For_C mode, there is no rotate right in C,
10479 -- so we rewrite in terms of logical shifts
10480
10481 -- Shift_Right (Num, Bits) or Shift_Left (num, Esize - Bits)
10482
10483 -- where Bits is the shift count mod Esize (the mod operation here
10484 -- deals with ludicrous large shift counts, which are apparently OK).
10485
8ad6af8f
AC
10486 if Modify_Tree_For_C then
10487 declare
10488 Loc : constant Source_Ptr := Sloc (N);
10489 Rtp : constant Entity_Id := Etype (Right_Opnd (N));
10490 Typ : constant Entity_Id := Etype (N);
5216b599 10491
8ad6af8f
AC
10492 begin
10493 -- Sem_Intr should prevent getting there with a non binary modulus
5216b599 10494
8ad6af8f
AC
10495 pragma Assert (not Non_Binary_Modulus (Typ));
10496
10497 Rewrite (Right_Opnd (N),
10498 Make_Op_Rem (Loc,
10499 Left_Opnd => Relocate_Node (Right_Opnd (N)),
10500 Right_Opnd => Make_Integer_Literal (Loc, Esize (Typ))));
5216b599 10501
8ad6af8f 10502 Analyze_And_Resolve (Right_Opnd (N), Rtp);
5216b599 10503
5216b599
AC
10504 Rewrite (N,
10505 Make_Op_Or (Loc,
10506 Left_Opnd =>
10507 Make_Op_Shift_Right (Loc,
10508 Left_Opnd => Left_Opnd (N),
10509 Right_Opnd => Right_Opnd (N)),
e09a5598 10510
5216b599
AC
10511 Right_Opnd =>
10512 Make_Op_Shift_Left (Loc,
10513 Left_Opnd => Duplicate_Subexpr_No_Checks (Left_Opnd (N)),
10514 Right_Opnd =>
10515 Make_Op_Subtract (Loc,
10516 Left_Opnd => Make_Integer_Literal (Loc, Esize (Typ)),
10517 Right_Opnd =>
10518 Duplicate_Subexpr_No_Checks (Right_Opnd (N))))));
10519
10520 Analyze_And_Resolve (N, Typ);
8ad6af8f
AC
10521 end;
10522 end if;
70482933
RK
10523 end Expand_N_Op_Rotate_Right;
10524
10525 ----------------------------
10526 -- Expand_N_Op_Shift_Left --
10527 ----------------------------
10528
e09a5598
AC
10529 -- Note: nothing in this routine depends on left as opposed to right shifts
10530 -- so we share the routine for expanding shift right operations.
10531
70482933
RK
10532 procedure Expand_N_Op_Shift_Left (N : Node_Id) is
10533 begin
10534 Binary_Op_Validity_Checks (N);
e09a5598
AC
10535
10536 -- If we are in Modify_Tree_For_C mode, then ensure that the right
10537 -- operand is not greater than the word size (since that would not
10538 -- be defined properly by the corresponding C shift operator).
10539
10540 if Modify_Tree_For_C then
10541 declare
10542 Right : constant Node_Id := Right_Opnd (N);
10543 Loc : constant Source_Ptr := Sloc (Right);
10544 Typ : constant Entity_Id := Etype (N);
10545 Siz : constant Uint := Esize (Typ);
10546 Orig : Node_Id;
10547 OK : Boolean;
10548 Lo : Uint;
10549 Hi : Uint;
10550
10551 begin
8ad6af8f
AC
10552 -- Sem_Intr should prevent getting there with a non binary modulus
10553
10554 pragma Assert (not Non_Binary_Modulus (Typ));
10555
e09a5598
AC
10556 if Compile_Time_Known_Value (Right) then
10557 if Expr_Value (Right) >= Siz then
10558 Rewrite (N, Make_Integer_Literal (Loc, 0));
10559 Analyze_And_Resolve (N, Typ);
10560 end if;
10561
10562 -- Not compile time known, find range
10563
10564 else
10565 Determine_Range (Right, OK, Lo, Hi, Assume_Valid => True);
10566
10567 -- Nothing to do if known to be OK range, otherwise expand
10568
10569 if not OK or else Hi >= Siz then
10570
10571 -- Prevent recursion on copy of shift node
10572
10573 Orig := Relocate_Node (N);
10574 Set_Analyzed (Orig);
10575
10576 -- Now do the rewrite
10577
10578 Rewrite (N,
10579 Make_If_Expression (Loc,
10580 Expressions => New_List (
10581 Make_Op_Ge (Loc,
10582 Left_Opnd => Duplicate_Subexpr_Move_Checks (Right),
10583 Right_Opnd => Make_Integer_Literal (Loc, Siz)),
10584 Make_Integer_Literal (Loc, 0),
10585 Orig)));
10586 Analyze_And_Resolve (N, Typ);
10587 end if;
10588 end if;
10589 end;
10590 end if;
70482933
RK
10591 end Expand_N_Op_Shift_Left;
10592
10593 -----------------------------
10594 -- Expand_N_Op_Shift_Right --
10595 -----------------------------
10596
10597 procedure Expand_N_Op_Shift_Right (N : Node_Id) is
10598 begin
e09a5598
AC
10599 -- Share shift left circuit
10600
10601 Expand_N_Op_Shift_Left (N);
70482933
RK
10602 end Expand_N_Op_Shift_Right;
10603
10604 ----------------------------------------
10605 -- Expand_N_Op_Shift_Right_Arithmetic --
10606 ----------------------------------------
10607
10608 procedure Expand_N_Op_Shift_Right_Arithmetic (N : Node_Id) is
10609 begin
10610 Binary_Op_Validity_Checks (N);
5216b599
AC
10611
10612 -- If we are in Modify_Tree_For_C mode, there is no shift right
8ad6af8f
AC
10613 -- arithmetic in C, so we rewrite in terms of logical shifts for
10614 -- modular integers, and keep the Shift_Right intrinsic for signed
10615 -- integers: even though doing a shift on a signed integer is not
10616 -- fully guaranteed by the C standard, this is what C compilers
10617 -- implement in practice.
10618 -- Consider also taking advantage of this for modular integers by first
10619 -- performing an unchecked conversion of the modular integer to a signed
10620 -- integer of the same sign, and then convert back.
5216b599
AC
10621
10622 -- Shift_Right (Num, Bits) or
10623 -- (if Num >= Sign
10624 -- then not (Shift_Right (Mask, bits))
10625 -- else 0)
10626
10627 -- Here Mask is all 1 bits (2**size - 1), and Sign is 2**(size - 1)
10628
e09a5598
AC
10629 -- Note: the above works fine for shift counts greater than or equal
10630 -- to the word size, since in this case (not (Shift_Right (Mask, bits)))
10631 -- generates all 1'bits.
10632
8ad6af8f
AC
10633 if Modify_Tree_For_C and then Is_Modular_Integer_Type (Etype (N)) then
10634 declare
10635 Loc : constant Source_Ptr := Sloc (N);
10636 Typ : constant Entity_Id := Etype (N);
10637 Sign : constant Uint := 2 ** (Esize (Typ) - 1);
10638 Mask : constant Uint := (2 ** Esize (Typ)) - 1;
10639 Left : constant Node_Id := Left_Opnd (N);
10640 Right : constant Node_Id := Right_Opnd (N);
10641 Maskx : Node_Id;
5216b599 10642
8ad6af8f
AC
10643 begin
10644 -- Sem_Intr should prevent getting there with a non binary modulus
5216b599 10645
8ad6af8f 10646 pragma Assert (not Non_Binary_Modulus (Typ));
5216b599
AC
10647
10648 -- Here if not (Shift_Right (Mask, bits)) can be computed at
10649 -- compile time as a single constant.
10650
10651 if Compile_Time_Known_Value (Right) then
10652 declare
10653 Val : constant Uint := Expr_Value (Right);
10654
10655 begin
10656 if Val >= Esize (Typ) then
10657 Maskx := Make_Integer_Literal (Loc, Mask);
10658
10659 else
10660 Maskx :=
10661 Make_Integer_Literal (Loc,
10662 Intval => Mask - (Mask / (2 ** Expr_Value (Right))));
10663 end if;
10664 end;
10665
10666 else
10667 Maskx :=
10668 Make_Op_Not (Loc,
10669 Right_Opnd =>
10670 Make_Op_Shift_Right (Loc,
10671 Left_Opnd => Make_Integer_Literal (Loc, Mask),
10672 Right_Opnd => Duplicate_Subexpr_No_Checks (Right)));
10673 end if;
10674
10675 -- Now do the rewrite
10676
10677 Rewrite (N,
10678 Make_Op_Or (Loc,
10679 Left_Opnd =>
10680 Make_Op_Shift_Right (Loc,
10681 Left_Opnd => Left,
10682 Right_Opnd => Right),
10683 Right_Opnd =>
10684 Make_If_Expression (Loc,
10685 Expressions => New_List (
10686 Make_Op_Ge (Loc,
10687 Left_Opnd => Duplicate_Subexpr_No_Checks (Left),
10688 Right_Opnd => Make_Integer_Literal (Loc, Sign)),
10689 Maskx,
10690 Make_Integer_Literal (Loc, 0)))));
10691 Analyze_And_Resolve (N, Typ);
8ad6af8f
AC
10692 end;
10693 end if;
70482933
RK
10694 end Expand_N_Op_Shift_Right_Arithmetic;
10695
10696 --------------------------
10697 -- Expand_N_Op_Subtract --
10698 --------------------------
10699
10700 procedure Expand_N_Op_Subtract (N : Node_Id) is
10701 Typ : constant Entity_Id := Etype (N);
10702
10703 begin
10704 Binary_Op_Validity_Checks (N);
10705
b6b5cca8
AC
10706 -- Check for MINIMIZED/ELIMINATED overflow mode
10707
10708 if Minimized_Eliminated_Overflow_Check (N) then
10709 Apply_Arithmetic_Overflow_Check (N);
10710 return;
10711 end if;
10712
6c8e4f7e
EB
10713 -- Try to narrow the operation
10714
10715 if Typ = Universal_Integer then
10716 Narrow_Large_Operation (N);
10717
10718 if Nkind (N) /= N_Op_Subtract then
10719 return;
10720 end if;
10721 end if;
10722
70482933
RK
10723 -- N - 0 = N for integer types
10724
10725 if Is_Integer_Type (Typ)
10726 and then Compile_Time_Known_Value (Right_Opnd (N))
10727 and then Expr_Value (Right_Opnd (N)) = 0
10728 then
10729 Rewrite (N, Left_Opnd (N));
10730 return;
10731 end if;
10732
8fc789c8 10733 -- Arithmetic overflow checks for signed integer/fixed point types
70482933 10734
761f7dcb 10735 if Is_Signed_Integer_Type (Typ) or else Is_Fixed_Point_Type (Typ) then
70482933 10736 Apply_Arithmetic_Overflow_Check (N);
70482933 10737 end if;
dfaff97b
RD
10738
10739 -- Overflow checks for floating-point if -gnateF mode active
10740
10741 Check_Float_Op_Overflow (N);
05dbb83f 10742
f4ac86dd 10743 Expand_Nonbinary_Modular_Op (N);
70482933
RK
10744 end Expand_N_Op_Subtract;
10745
10746 ---------------------
10747 -- Expand_N_Op_Xor --
10748 ---------------------
10749
10750 procedure Expand_N_Op_Xor (N : Node_Id) is
10751 Typ : constant Entity_Id := Etype (N);
10752
10753 begin
10754 Binary_Op_Validity_Checks (N);
10755
10756 if Is_Array_Type (Etype (N)) then
10757 Expand_Boolean_Operator (N);
10758
10759 elsif Is_Boolean_Type (Etype (N)) then
10760 Adjust_Condition (Left_Opnd (N));
10761 Adjust_Condition (Right_Opnd (N));
10762 Set_Etype (N, Standard_Boolean);
10763 Adjust_Result_Type (N, Typ);
437f8c1e
AC
10764
10765 elsif Is_Intrinsic_Subprogram (Entity (N)) then
10766 Expand_Intrinsic_Call (N, Entity (N));
70482933 10767 end if;
9cd7bc5e
ES
10768
10769 Expand_Nonbinary_Modular_Op (N);
70482933
RK
10770 end Expand_N_Op_Xor;
10771
10772 ----------------------
10773 -- Expand_N_Or_Else --
10774 ----------------------
10775
5875f8d6
AC
10776 procedure Expand_N_Or_Else (N : Node_Id)
10777 renames Expand_Short_Circuit_Operator;
70482933
RK
10778
10779 -----------------------------------
10780 -- Expand_N_Qualified_Expression --
10781 -----------------------------------
10782
10783 procedure Expand_N_Qualified_Expression (N : Node_Id) is
10784 Operand : constant Node_Id := Expression (N);
10785 Target_Type : constant Entity_Id := Entity (Subtype_Mark (N));
10786
10787 begin
f82944b7
JM
10788 -- Do validity check if validity checking operands
10789
533369aa 10790 if Validity_Checks_On and Validity_Check_Operands then
f82944b7
JM
10791 Ensure_Valid (Operand);
10792 end if;
10793
10794 -- Apply possible constraint check
10795
70482933 10796 Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
d79e621a 10797
24eda9e7
GD
10798 -- Apply possible predicate check
10799
10800 Apply_Predicate_Check (Operand, Target_Type);
10801
d79e621a 10802 if Do_Range_Check (Operand) then
d79e621a
GD
10803 Generate_Range_Check (Operand, Target_Type, CE_Range_Check_Failed);
10804 end if;
70482933
RK
10805 end Expand_N_Qualified_Expression;
10806
a961aa79
AC
10807 ------------------------------------
10808 -- Expand_N_Quantified_Expression --
10809 ------------------------------------
10810
c0f136cd
AC
10811 -- We expand:
10812
10813 -- for all X in range => Cond
a961aa79 10814
c0f136cd 10815 -- into:
a961aa79 10816
c0f136cd
AC
10817 -- T := True;
10818 -- for X in range loop
10819 -- if not Cond then
10820 -- T := False;
10821 -- exit;
10822 -- end if;
10823 -- end loop;
90c63b09 10824
36504e5f 10825 -- Similarly, an existentially quantified expression:
90c63b09 10826
c0f136cd 10827 -- for some X in range => Cond
90c63b09 10828
c0f136cd 10829 -- becomes:
90c63b09 10830
c0f136cd
AC
10831 -- T := False;
10832 -- for X in range loop
10833 -- if Cond then
10834 -- T := True;
10835 -- exit;
10836 -- end if;
10837 -- end loop;
90c63b09 10838
c0f136cd
AC
10839 -- In both cases, the iteration may be over a container in which case it is
10840 -- given by an iterator specification, not a loop parameter specification.
a961aa79 10841
c0f136cd 10842 procedure Expand_N_Quantified_Expression (N : Node_Id) is
804670f1
AC
10843 Actions : constant List_Id := New_List;
10844 For_All : constant Boolean := All_Present (N);
10845 Iter_Spec : constant Node_Id := Iterator_Specification (N);
10846 Loc : constant Source_Ptr := Sloc (N);
10847 Loop_Spec : constant Node_Id := Loop_Parameter_Specification (N);
10848 Cond : Node_Id;
10849 Flag : Entity_Id;
10850 Scheme : Node_Id;
10851 Stmts : List_Id;
16b9e3c3 10852 Var : Entity_Id;
c56a9ba4 10853
a961aa79 10854 begin
16b9e3c3
ES
10855 -- Ensure that the bound variable is properly frozen. We must do
10856 -- this before expansion because the expression is about to be
10857 -- converted into a loop, and resulting freeze nodes may end up
10858 -- in the wrong place in the tree.
10859
10860 if Present (Iter_Spec) then
10861 Var := Defining_Identifier (Iter_Spec);
10862 else
10863 Var := Defining_Identifier (Loop_Spec);
10864 end if;
10865
10866 declare
10867 P : Node_Id := Parent (N);
10868 begin
10869 while Nkind (P) in N_Subexpr loop
10870 P := Parent (P);
10871 end loop;
10872
10873 Freeze_Before (P, Etype (Var));
10874 end;
10875
804670f1
AC
10876 -- Create the declaration of the flag which tracks the status of the
10877 -- quantified expression. Generate:
011f9d5d 10878
804670f1 10879 -- Flag : Boolean := (True | False);
011f9d5d 10880
804670f1 10881 Flag := Make_Temporary (Loc, 'T', N);
011f9d5d 10882
804670f1 10883 Append_To (Actions,
90c63b09 10884 Make_Object_Declaration (Loc,
804670f1 10885 Defining_Identifier => Flag,
c0f136cd
AC
10886 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
10887 Expression =>
804670f1
AC
10888 New_Occurrence_Of (Boolean_Literals (For_All), Loc)));
10889
10890 -- Construct the circuitry which tracks the status of the quantified
10891 -- expression. Generate:
10892
10893 -- if [not] Cond then
10894 -- Flag := (False | True);
10895 -- exit;
10896 -- end if;
a961aa79 10897
c0f136cd 10898 Cond := Relocate_Node (Condition (N));
a961aa79 10899
804670f1 10900 if For_All then
c0f136cd 10901 Cond := Make_Op_Not (Loc, Cond);
a961aa79
AC
10902 end if;
10903
804670f1 10904 Stmts := New_List (
c0f136cd
AC
10905 Make_Implicit_If_Statement (N,
10906 Condition => Cond,
10907 Then_Statements => New_List (
10908 Make_Assignment_Statement (Loc,
804670f1 10909 Name => New_Occurrence_Of (Flag, Loc),
c0f136cd 10910 Expression =>
804670f1
AC
10911 New_Occurrence_Of (Boolean_Literals (not For_All), Loc)),
10912 Make_Exit_Statement (Loc))));
10913
10914 -- Build the loop equivalent of the quantified expression
c0f136cd 10915
804670f1
AC
10916 if Present (Iter_Spec) then
10917 Scheme :=
011f9d5d 10918 Make_Iteration_Scheme (Loc,
804670f1 10919 Iterator_Specification => Iter_Spec);
c56a9ba4 10920 else
804670f1 10921 Scheme :=
011f9d5d 10922 Make_Iteration_Scheme (Loc,
804670f1 10923 Loop_Parameter_Specification => Loop_Spec);
c56a9ba4
AC
10924 end if;
10925
a961aa79
AC
10926 Append_To (Actions,
10927 Make_Loop_Statement (Loc,
804670f1
AC
10928 Iteration_Scheme => Scheme,
10929 Statements => Stmts,
c0f136cd 10930 End_Label => Empty));
a961aa79 10931
804670f1
AC
10932 -- Transform the quantified expression
10933
a961aa79
AC
10934 Rewrite (N,
10935 Make_Expression_With_Actions (Loc,
804670f1 10936 Expression => New_Occurrence_Of (Flag, Loc),
a961aa79 10937 Actions => Actions));
a961aa79
AC
10938 Analyze_And_Resolve (N, Standard_Boolean);
10939 end Expand_N_Quantified_Expression;
10940
70482933
RK
10941 ---------------------------------
10942 -- Expand_N_Selected_Component --
10943 ---------------------------------
10944
70482933
RK
10945 procedure Expand_N_Selected_Component (N : Node_Id) is
10946 Loc : constant Source_Ptr := Sloc (N);
10947 Par : constant Node_Id := Parent (N);
10948 P : constant Node_Id := Prefix (N);
03eb6036 10949 S : constant Node_Id := Selector_Name (N);
f715a5bd 10950 Ptyp : constant Entity_Id := Underlying_Type (Etype (P));
70482933 10951 Disc : Entity_Id;
70482933 10952 New_N : Node_Id;
fbf5a39b 10953 Dcon : Elmt_Id;
d606f1df 10954 Dval : Node_Id;
70482933
RK
10955
10956 function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
10957 -- Gigi needs a temporary for prefixes that depend on a discriminant,
10958 -- unless the context of an assignment can provide size information.
fbf5a39b
AC
10959 -- Don't we have a general routine that does this???
10960
53f29d4f
AC
10961 function Is_Subtype_Declaration return Boolean;
10962 -- The replacement of a discriminant reference by its value is required
4317e442
AC
10963 -- if this is part of the initialization of an temporary generated by a
10964 -- change of representation. This shows up as the construction of a
53f29d4f 10965 -- discriminant constraint for a subtype declared at the same point as
4317e442
AC
10966 -- the entity in the prefix of the selected component. We recognize this
10967 -- case when the context of the reference is:
10968 -- subtype ST is T(Obj.D);
10969 -- where the entity for Obj comes from source, and ST has the same sloc.
53f29d4f 10970
fbf5a39b
AC
10971 -----------------------
10972 -- In_Left_Hand_Side --
10973 -----------------------
70482933
RK
10974
10975 function In_Left_Hand_Side (Comp : Node_Id) return Boolean is
10976 begin
fbf5a39b 10977 return (Nkind (Parent (Comp)) = N_Assignment_Statement
90c63b09 10978 and then Comp = Name (Parent (Comp)))
fbf5a39b 10979 or else (Present (Parent (Comp))
90c63b09
AC
10980 and then Nkind (Parent (Comp)) in N_Subexpr
10981 and then In_Left_Hand_Side (Parent (Comp)));
70482933
RK
10982 end In_Left_Hand_Side;
10983
53f29d4f
AC
10984 -----------------------------
10985 -- Is_Subtype_Declaration --
10986 -----------------------------
10987
10988 function Is_Subtype_Declaration return Boolean is
10989 Par : constant Node_Id := Parent (N);
53f29d4f
AC
10990 begin
10991 return
10992 Nkind (Par) = N_Index_Or_Discriminant_Constraint
10993 and then Nkind (Parent (Parent (Par))) = N_Subtype_Declaration
10994 and then Comes_From_Source (Entity (Prefix (N)))
10995 and then Sloc (Par) = Sloc (Entity (Prefix (N)));
10996 end Is_Subtype_Declaration;
10997
fbf5a39b
AC
10998 -- Start of processing for Expand_N_Selected_Component
10999
70482933 11000 begin
fbf5a39b
AC
11001 -- Deal with discriminant check required
11002
70482933 11003 if Do_Discriminant_Check (N) then
03eb6036
AC
11004 if Present (Discriminant_Checking_Func
11005 (Original_Record_Component (Entity (S))))
11006 then
11007 -- Present the discriminant checking function to the backend, so
11008 -- that it can inline the call to the function.
11009
11010 Add_Inlined_Body
11011 (Discriminant_Checking_Func
cf27c5a2
EB
11012 (Original_Record_Component (Entity (S))),
11013 N);
70482933 11014
03eb6036 11015 -- Now reset the flag and generate the call
70482933 11016
03eb6036
AC
11017 Set_Do_Discriminant_Check (N, False);
11018 Generate_Discriminant_Check (N);
70482933 11019
03eb6036
AC
11020 -- In the case of Unchecked_Union, no discriminant checking is
11021 -- actually performed.
70482933 11022
03eb6036
AC
11023 else
11024 Set_Do_Discriminant_Check (N, False);
11025 end if;
70482933
RK
11026 end if;
11027
b4592168
GD
11028 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
11029 -- function, then additional actuals must be passed.
11030
d4dfb005 11031 if Is_Build_In_Place_Function_Call (P) then
b4592168 11032 Make_Build_In_Place_Call_In_Anonymous_Context (P);
4ac62786
AC
11033
11034 -- Ada 2005 (AI-318-02): Specialization of the previous case for prefix
11035 -- containing build-in-place function calls whose returned object covers
11036 -- interface types.
11037
d4dfb005 11038 elsif Present (Unqual_BIP_Iface_Function_Call (P)) then
4ac62786 11039 Make_Build_In_Place_Iface_Call_In_Anonymous_Context (P);
b4592168
GD
11040 end if;
11041
fbf5a39b
AC
11042 -- Gigi cannot handle unchecked conversions that are the prefix of a
11043 -- selected component with discriminants. This must be checked during
11044 -- expansion, because during analysis the type of the selector is not
11045 -- known at the point the prefix is analyzed. If the conversion is the
11046 -- target of an assignment, then we cannot force the evaluation.
70482933
RK
11047
11048 if Nkind (Prefix (N)) = N_Unchecked_Type_Conversion
11049 and then Has_Discriminants (Etype (N))
11050 and then not In_Left_Hand_Side (N)
11051 then
11052 Force_Evaluation (Prefix (N));
11053 end if;
11054
11055 -- Remaining processing applies only if selector is a discriminant
11056
11057 if Ekind (Entity (Selector_Name (N))) = E_Discriminant then
11058
11059 -- If the selector is a discriminant of a constrained record type,
fbf5a39b
AC
11060 -- we may be able to rewrite the expression with the actual value
11061 -- of the discriminant, a useful optimization in some cases.
70482933
RK
11062
11063 if Is_Record_Type (Ptyp)
11064 and then Has_Discriminants (Ptyp)
11065 and then Is_Constrained (Ptyp)
70482933 11066 then
fbf5a39b 11067 -- Do this optimization for discrete types only, and not for
a90bd866 11068 -- access types (access discriminants get us into trouble).
70482933 11069
fbf5a39b
AC
11070 if not Is_Discrete_Type (Etype (N)) then
11071 null;
11072
356ffab8 11073 -- Don't do this on the left-hand side of an assignment statement.
0d901290
AC
11074 -- Normally one would think that references like this would not
11075 -- occur, but they do in generated code, and mean that we really
a90bd866 11076 -- do want to assign the discriminant.
fbf5a39b
AC
11077
11078 elsif Nkind (Par) = N_Assignment_Statement
11079 and then Name (Par) = N
11080 then
11081 null;
11082
685094bf 11083 -- Don't do this optimization for the prefix of an attribute or
e2534738 11084 -- the name of an object renaming declaration since these are
685094bf 11085 -- contexts where we do not want the value anyway.
fbf5a39b
AC
11086
11087 elsif (Nkind (Par) = N_Attribute_Reference
533369aa 11088 and then Prefix (Par) = N)
fbf5a39b
AC
11089 or else Is_Renamed_Object (N)
11090 then
11091 null;
11092
11093 -- Don't do this optimization if we are within the code for a
11094 -- discriminant check, since the whole point of such a check may
a90bd866 11095 -- be to verify the condition on which the code below depends.
fbf5a39b
AC
11096
11097 elsif Is_In_Discriminant_Check (N) then
11098 null;
11099
11100 -- Green light to see if we can do the optimization. There is
685094bf
RD
11101 -- still one condition that inhibits the optimization below but
11102 -- now is the time to check the particular discriminant.
fbf5a39b
AC
11103
11104 else
685094bf
RD
11105 -- Loop through discriminants to find the matching discriminant
11106 -- constraint to see if we can copy it.
fbf5a39b
AC
11107
11108 Disc := First_Discriminant (Ptyp);
11109 Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
11110 Discr_Loop : while Present (Dcon) loop
d606f1df 11111 Dval := Node (Dcon);
fbf5a39b 11112
bd949ee2
RD
11113 -- Check if this is the matching discriminant and if the
11114 -- discriminant value is simple enough to make sense to
11115 -- copy. We don't want to copy complex expressions, and
11116 -- indeed to do so can cause trouble (before we put in
11117 -- this guard, a discriminant expression containing an
e7d897b8 11118 -- AND THEN was copied, causing problems for coverage
c228a069 11119 -- analysis tools).
bd949ee2 11120
53f29d4f
AC
11121 -- However, if the reference is part of the initialization
11122 -- code generated for an object declaration, we must use
11123 -- the discriminant value from the subtype constraint,
11124 -- because the selected component may be a reference to the
11125 -- object being initialized, whose discriminant is not yet
11126 -- set. This only happens in complex cases involving changes
84be0369 11127 -- of representation.
53f29d4f 11128
bd949ee2
RD
11129 if Disc = Entity (Selector_Name (N))
11130 and then (Is_Entity_Name (Dval)
170b2989
AC
11131 or else Compile_Time_Known_Value (Dval)
11132 or else Is_Subtype_Declaration)
bd949ee2 11133 then
fbf5a39b
AC
11134 -- Here we have the matching discriminant. Check for
11135 -- the case of a discriminant of a component that is
11136 -- constrained by an outer discriminant, which cannot
11137 -- be optimized away.
11138
84be0369 11139 if Denotes_Discriminant (Dval, Check_Concurrent => True)
d606f1df
AC
11140 then
11141 exit Discr_Loop;
11142
11143 -- Do not retrieve value if constraint is not static. It
11144 -- is generally not useful, and the constraint may be a
11145 -- rewritten outer discriminant in which case it is in
11146 -- fact incorrect.
11147
11148 elsif Is_Entity_Name (Dval)
d606f1df 11149 and then
533369aa
AC
11150 Nkind (Parent (Entity (Dval))) = N_Object_Declaration
11151 and then Present (Expression (Parent (Entity (Dval))))
11152 and then not
edab6088 11153 Is_OK_Static_Expression
d606f1df 11154 (Expression (Parent (Entity (Dval))))
fbf5a39b
AC
11155 then
11156 exit Discr_Loop;
70482933 11157
685094bf
RD
11158 -- In the context of a case statement, the expression may
11159 -- have the base type of the discriminant, and we need to
11160 -- preserve the constraint to avoid spurious errors on
11161 -- missing cases.
70482933 11162
fbf5a39b 11163 elsif Nkind (Parent (N)) = N_Case_Statement
d606f1df 11164 and then Etype (Dval) /= Etype (Disc)
70482933
RK
11165 then
11166 Rewrite (N,
11167 Make_Qualified_Expression (Loc,
fbf5a39b
AC
11168 Subtype_Mark =>
11169 New_Occurrence_Of (Etype (Disc), Loc),
11170 Expression =>
d606f1df 11171 New_Copy_Tree (Dval)));
ffe9aba8 11172 Analyze_And_Resolve (N, Etype (Disc));
fbf5a39b
AC
11173
11174 -- In case that comes out as a static expression,
11175 -- reset it (a selected component is never static).
11176
11177 Set_Is_Static_Expression (N, False);
11178 return;
11179
11180 -- Otherwise we can just copy the constraint, but the
a90bd866 11181 -- result is certainly not static. In some cases the
ffe9aba8
AC
11182 -- discriminant constraint has been analyzed in the
11183 -- context of the original subtype indication, but for
11184 -- itypes the constraint might not have been analyzed
11185 -- yet, and this must be done now.
fbf5a39b 11186
70482933 11187 else
d606f1df 11188 Rewrite (N, New_Copy_Tree (Dval));
ffe9aba8 11189 Analyze_And_Resolve (N);
fbf5a39b
AC
11190 Set_Is_Static_Expression (N, False);
11191 return;
70482933 11192 end if;
70482933
RK
11193 end if;
11194
fbf5a39b
AC
11195 Next_Elmt (Dcon);
11196 Next_Discriminant (Disc);
11197 end loop Discr_Loop;
70482933 11198
fbf5a39b
AC
11199 -- Note: the above loop should always find a matching
11200 -- discriminant, but if it does not, we just missed an
c228a069
AC
11201 -- optimization due to some glitch (perhaps a previous
11202 -- error), so ignore.
fbf5a39b
AC
11203
11204 end if;
70482933
RK
11205 end if;
11206
11207 -- The only remaining processing is in the case of a discriminant of
11208 -- a concurrent object, where we rewrite the prefix to denote the
11209 -- corresponding record type. If the type is derived and has renamed
11210 -- discriminants, use corresponding discriminant, which is the one
11211 -- that appears in the corresponding record.
11212
11213 if not Is_Concurrent_Type (Ptyp) then
11214 return;
11215 end if;
11216
11217 Disc := Entity (Selector_Name (N));
11218
11219 if Is_Derived_Type (Ptyp)
11220 and then Present (Corresponding_Discriminant (Disc))
11221 then
11222 Disc := Corresponding_Discriminant (Disc);
11223 end if;
11224
11225 New_N :=
11226 Make_Selected_Component (Loc,
11227 Prefix =>
11228 Unchecked_Convert_To (Corresponding_Record_Type (Ptyp),
11229 New_Copy_Tree (P)),
11230 Selector_Name => Make_Identifier (Loc, Chars (Disc)));
11231
11232 Rewrite (N, New_N);
11233 Analyze (N);
11234 end if;
5972791c 11235
73fe1679 11236 -- Set Atomic_Sync_Required if necessary for atomic component
5972791c 11237
73fe1679
AC
11238 if Nkind (N) = N_Selected_Component then
11239 declare
11240 E : constant Entity_Id := Entity (Selector_Name (N));
11241 Set : Boolean;
11242
11243 begin
11244 -- If component is atomic, but type is not, setting depends on
11245 -- disable/enable state for the component.
11246
11247 if Is_Atomic (E) and then not Is_Atomic (Etype (E)) then
11248 Set := not Atomic_Synchronization_Disabled (E);
11249
11250 -- If component is not atomic, but its type is atomic, setting
11251 -- depends on disable/enable state for the type.
11252
11253 elsif not Is_Atomic (E) and then Is_Atomic (Etype (E)) then
11254 Set := not Atomic_Synchronization_Disabled (Etype (E));
11255
11256 -- If both component and type are atomic, we disable if either
11257 -- component or its type have sync disabled.
11258
11259 elsif Is_Atomic (E) and then Is_Atomic (Etype (E)) then
11260 Set := (not Atomic_Synchronization_Disabled (E))
11261 and then
11262 (not Atomic_Synchronization_Disabled (Etype (E)));
11263
11264 else
11265 Set := False;
11266 end if;
11267
11268 -- Set flag if required
11269
11270 if Set then
11271 Activate_Atomic_Synchronization (N);
11272 end if;
11273 end;
5972791c 11274 end if;
70482933
RK
11275 end Expand_N_Selected_Component;
11276
11277 --------------------
11278 -- Expand_N_Slice --
11279 --------------------
11280
11281 procedure Expand_N_Slice (N : Node_Id) is
5ff90f08
AC
11282 Loc : constant Source_Ptr := Sloc (N);
11283 Typ : constant Entity_Id := Etype (N);
fbf5a39b 11284
81a5b587 11285 function Is_Procedure_Actual (N : Node_Id) return Boolean;
685094bf
RD
11286 -- Check whether the argument is an actual for a procedure call, in
11287 -- which case the expansion of a bit-packed slice is deferred until the
11288 -- call itself is expanded. The reason this is required is that we might
11289 -- have an IN OUT or OUT parameter, and the copy out is essential, and
11290 -- that copy out would be missed if we created a temporary here in
11291 -- Expand_N_Slice. Note that we don't bother to test specifically for an
11292 -- IN OUT or OUT mode parameter, since it is a bit tricky to do, and it
11293 -- is harmless to defer expansion in the IN case, since the call
11294 -- processing will still generate the appropriate copy in operation,
11295 -- which will take care of the slice.
81a5b587 11296
b01bf852 11297 procedure Make_Temporary_For_Slice;
685094bf 11298 -- Create a named variable for the value of the slice, in cases where
c7a494c9 11299 -- the back end cannot handle it properly, e.g. when packed types or
685094bf 11300 -- unaligned slices are involved.
fbf5a39b 11301
81a5b587
AC
11302 -------------------------
11303 -- Is_Procedure_Actual --
11304 -------------------------
11305
11306 function Is_Procedure_Actual (N : Node_Id) return Boolean is
11307 Par : Node_Id := Parent (N);
08aa9a4a 11308
81a5b587 11309 begin
81a5b587 11310 loop
c6a60aa1
RD
11311 -- If our parent is a procedure call we can return
11312
81a5b587
AC
11313 if Nkind (Par) = N_Procedure_Call_Statement then
11314 return True;
6b6fcd3e 11315
685094bf
RD
11316 -- If our parent is a type conversion, keep climbing the tree,
11317 -- since a type conversion can be a procedure actual. Also keep
11318 -- climbing if parameter association or a qualified expression,
11319 -- since these are additional cases that do can appear on
11320 -- procedure actuals.
6b6fcd3e 11321
4a08c95c
AC
11322 elsif Nkind (Par) in N_Type_Conversion
11323 | N_Parameter_Association
11324 | N_Qualified_Expression
c6a60aa1 11325 then
81a5b587 11326 Par := Parent (Par);
c6a60aa1
RD
11327
11328 -- Any other case is not what we are looking for
11329
11330 else
11331 return False;
81a5b587
AC
11332 end if;
11333 end loop;
81a5b587
AC
11334 end Is_Procedure_Actual;
11335
b01bf852
AC
11336 ------------------------------
11337 -- Make_Temporary_For_Slice --
11338 ------------------------------
fbf5a39b 11339
b01bf852 11340 procedure Make_Temporary_For_Slice is
b01bf852 11341 Ent : constant Entity_Id := Make_Temporary (Loc, 'T', N);
5ff90f08 11342 Decl : Node_Id;
13d923cc 11343
fbf5a39b
AC
11344 begin
11345 Decl :=
11346 Make_Object_Declaration (Loc,
11347 Defining_Identifier => Ent,
11348 Object_Definition => New_Occurrence_Of (Typ, Loc));
11349
11350 Set_No_Initialization (Decl);
11351
11352 Insert_Actions (N, New_List (
11353 Decl,
11354 Make_Assignment_Statement (Loc,
5ff90f08 11355 Name => New_Occurrence_Of (Ent, Loc),
fbf5a39b
AC
11356 Expression => Relocate_Node (N))));
11357
11358 Rewrite (N, New_Occurrence_Of (Ent, Loc));
11359 Analyze_And_Resolve (N, Typ);
b01bf852 11360 end Make_Temporary_For_Slice;
fbf5a39b 11361
5ff90f08
AC
11362 -- Local variables
11363
800da977 11364 Pref : constant Node_Id := Prefix (N);
5ff90f08 11365
fbf5a39b 11366 -- Start of processing for Expand_N_Slice
70482933
RK
11367
11368 begin
b4592168
GD
11369 -- Ada 2005 (AI-318-02): If the prefix is a call to a build-in-place
11370 -- function, then additional actuals must be passed.
11371
d4dfb005 11372 if Is_Build_In_Place_Function_Call (Pref) then
5ff90f08 11373 Make_Build_In_Place_Call_In_Anonymous_Context (Pref);
4ac62786
AC
11374
11375 -- Ada 2005 (AI-318-02): Specialization of the previous case for prefix
11376 -- containing build-in-place function calls whose returned object covers
11377 -- interface types.
11378
d4dfb005 11379 elsif Present (Unqual_BIP_Iface_Function_Call (Pref)) then
4ac62786 11380 Make_Build_In_Place_Iface_Call_In_Anonymous_Context (Pref);
b4592168
GD
11381 end if;
11382
70482933
RK
11383 -- The remaining case to be handled is packed slices. We can leave
11384 -- packed slices as they are in the following situations:
11385
11386 -- 1. Right or left side of an assignment (we can handle this
11387 -- situation correctly in the assignment statement expansion).
11388
685094bf
RD
11389 -- 2. Prefix of indexed component (the slide is optimized away in this
11390 -- case, see the start of Expand_N_Slice.)
70482933 11391
685094bf
RD
11392 -- 3. Object renaming declaration, since we want the name of the
11393 -- slice, not the value.
70482933 11394
685094bf
RD
11395 -- 4. Argument to procedure call, since copy-in/copy-out handling may
11396 -- be required, and this is handled in the expansion of call
11397 -- itself.
70482933 11398
685094bf
RD
11399 -- 5. Prefix of an address attribute (this is an error which is caught
11400 -- elsewhere, and the expansion would interfere with generating the
955379e4
EB
11401 -- error message) or of a size attribute (because 'Size may change
11402 -- when applied to the temporary instead of the slice directly).
70482933 11403
81a5b587 11404 if not Is_Packed (Typ) then
08aa9a4a 11405
685094bf
RD
11406 -- Apply transformation for actuals of a function call, where
11407 -- Expand_Actuals is not used.
81a5b587
AC
11408
11409 if Nkind (Parent (N)) = N_Function_Call
11410 and then Is_Possibly_Unaligned_Slice (N)
11411 then
b01bf852 11412 Make_Temporary_For_Slice;
81a5b587
AC
11413 end if;
11414
11415 elsif Nkind (Parent (N)) = N_Assignment_Statement
11416 or else (Nkind (Parent (Parent (N))) = N_Assignment_Statement
533369aa 11417 and then Parent (N) = Name (Parent (Parent (N))))
70482933 11418 then
81a5b587 11419 return;
70482933 11420
81a5b587
AC
11421 elsif Nkind (Parent (N)) = N_Indexed_Component
11422 or else Is_Renamed_Object (N)
11423 or else Is_Procedure_Actual (N)
11424 then
11425 return;
70482933 11426
91b1417d 11427 elsif Nkind (Parent (N)) = N_Attribute_Reference
955379e4
EB
11428 and then (Attribute_Name (Parent (N)) = Name_Address
11429 or else Attribute_Name (Parent (N)) = Name_Size)
fbf5a39b 11430 then
81a5b587
AC
11431 return;
11432
11433 else
b01bf852 11434 Make_Temporary_For_Slice;
70482933
RK
11435 end if;
11436 end Expand_N_Slice;
11437
11438 ------------------------------
11439 -- Expand_N_Type_Conversion --
11440 ------------------------------
11441
11442 procedure Expand_N_Type_Conversion (N : Node_Id) is
11443 Loc : constant Source_Ptr := Sloc (N);
11444 Operand : constant Node_Id := Expression (N);
1b2f53bb 11445 Operand_Acc : Node_Id := Operand;
8113b0c7 11446 Target_Type : Entity_Id := Etype (N);
70482933
RK
11447 Operand_Type : Entity_Id := Etype (Operand);
11448
8113b0c7
EB
11449 procedure Discrete_Range_Check;
11450 -- Handles generation of range check for discrete target value
11451
70482933 11452 procedure Handle_Changed_Representation;
685094bf
RD
11453 -- This is called in the case of record and array type conversions to
11454 -- see if there is a change of representation to be handled. Change of
11455 -- representation is actually handled at the assignment statement level,
11456 -- and what this procedure does is rewrite node N conversion as an
11457 -- assignment to temporary. If there is no change of representation,
11458 -- then the conversion node is unchanged.
70482933 11459
426908f8
RD
11460 procedure Raise_Accessibility_Error;
11461 -- Called when we know that an accessibility check will fail. Rewrites
11462 -- node N to an appropriate raise statement and outputs warning msgs.
91669e7e
AC
11463 -- The Etype of the raise node is set to Target_Type. Note that in this
11464 -- case the rest of the processing should be skipped (i.e. the call to
11465 -- this procedure will be followed by "goto Done").
426908f8 11466
70482933
RK
11467 procedure Real_Range_Check;
11468 -- Handles generation of range check for real target value
11469
d15f9422
AC
11470 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean;
11471 -- True iff Present (Effective_Extra_Accessibility (Id)) successfully
11472 -- evaluates to True.
11473
1a0d2909
JS
11474 function Statically_Deeper_Relation_Applies (Targ_Typ : Entity_Id)
11475 return Boolean;
11476 -- Given a target type for a conversion, determine whether the
11477 -- statically deeper accessibility rules apply to it.
11478
8113b0c7
EB
11479 --------------------------
11480 -- Discrete_Range_Check --
11481 --------------------------
11482
43eb2bb6
EB
11483 -- Case of conversions to a discrete type. We let Generate_Range_Check
11484 -- do the heavy lifting, after converting a fixed-point operand to an
11485 -- appropriate integer type.
8113b0c7
EB
11486
11487 procedure Discrete_Range_Check is
11488 Expr : Node_Id;
11489 Ityp : Entity_Id;
11490
646204de
JM
11491 procedure Generate_Temporary;
11492 -- Generate a temporary to facilitate in the C backend the code
11493 -- generation of the unchecked conversion since the size of the
11494 -- source type may differ from the size of the target type.
11495
11496 ------------------------
11497 -- Generate_Temporary --
11498 ------------------------
11499
11500 procedure Generate_Temporary is
11501 begin
11502 if Esize (Etype (Expr)) < Esize (Etype (Ityp)) then
11503 declare
11504 Exp_Type : constant Entity_Id := Ityp;
11505 Def_Id : constant Entity_Id :=
11506 Make_Temporary (Loc, 'R', Expr);
11507 E : Node_Id;
11508 Res : Node_Id;
11509
11510 begin
11511 Set_Is_Internal (Def_Id);
11512 Set_Etype (Def_Id, Exp_Type);
11513 Res := New_Occurrence_Of (Def_Id, Loc);
11514
11515 E :=
11516 Make_Object_Declaration (Loc,
11517 Defining_Identifier => Def_Id,
11518 Object_Definition => New_Occurrence_Of
11519 (Exp_Type, Loc),
11520 Constant_Present => True,
11521 Expression => Relocate_Node (Expr));
11522
11523 Set_Assignment_OK (E);
11524 Insert_Action (Expr, E);
11525
11526 Set_Assignment_OK (Res, Assignment_OK (Expr));
11527
11528 Rewrite (Expr, Res);
11529 Analyze_And_Resolve (Expr, Exp_Type);
11530 end;
11531 end if;
11532 end Generate_Temporary;
11533
11534 -- Start of processing for Discrete_Range_Check
11535
8113b0c7 11536 begin
17ea7fad 11537 -- Nothing more to do if conversion was rewritten
8113b0c7
EB
11538
11539 if Nkind (N) /= N_Type_Conversion then
11540 return;
11541 end if;
11542
11543 Expr := Expression (N);
11544
17ea7fad
AC
11545 -- Clear the Do_Range_Check flag on Expr
11546
11547 Set_Do_Range_Check (Expr, False);
11548
43eb2bb6
EB
11549 -- Nothing to do if range checks suppressed
11550
11551 if Range_Checks_Suppressed (Target_Type) then
11552 return;
11553 end if;
11554
11555 -- Nothing to do if expression is an entity on which checks have been
11556 -- suppressed.
11557
11558 if Is_Entity_Name (Expr)
11559 and then Range_Checks_Suppressed (Entity (Expr))
11560 then
11561 return;
11562 end if;
11563
8113b0c7
EB
11564 -- Before we do a range check, we have to deal with treating
11565 -- a fixed-point operand as an integer. The way we do this
11566 -- is simply to do an unchecked conversion to an appropriate
17ea7fad
AC
11567 -- integer type with the smallest size, so that we can suppress
11568 -- trivial checks.
8113b0c7
EB
11569
11570 if Is_Fixed_Point_Type (Etype (Expr)) then
17ea7fad
AC
11571 Ityp := Small_Integer_Type_For
11572 (Esize (Base_Type (Etype (Expr))), False);
8113b0c7 11573
17ea7fad
AC
11574 -- Generate a temporary with the integer type to facilitate in the
11575 -- C backend the code generation for the unchecked conversion.
646204de
JM
11576
11577 if Modify_Tree_For_C then
11578 Generate_Temporary;
11579 end if;
11580
8113b0c7
EB
11581 Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
11582 end if;
11583
a7191e01
EB
11584 -- Reset overflow flag, since the range check will include
11585 -- dealing with possible overflow, and generate the check.
11586
11587 Set_Do_Overflow_Check (N, False);
11588
8113b0c7
EB
11589 Generate_Range_Check (Expr, Target_Type, CE_Range_Check_Failed);
11590 end Discrete_Range_Check;
11591
70482933
RK
11592 -----------------------------------
11593 -- Handle_Changed_Representation --
11594 -----------------------------------
11595
11596 procedure Handle_Changed_Representation is
11597 Temp : Entity_Id;
11598 Decl : Node_Id;
11599 Odef : Node_Id;
70482933
RK
11600 N_Ix : Node_Id;
11601 Cons : List_Id;
11602
11603 begin
f82944b7 11604 -- Nothing else to do if no change of representation
70482933 11605
3968b02a 11606 if Has_Compatible_Representation (Target_Type, Operand_Type) then
70482933
RK
11607 return;
11608
11609 -- The real change of representation work is done by the assignment
11610 -- statement processing. So if this type conversion is appearing as
11611 -- the expression of an assignment statement, nothing needs to be
11612 -- done to the conversion.
11613
11614 elsif Nkind (Parent (N)) = N_Assignment_Statement then
11615 return;
11616
11617 -- Otherwise we need to generate a temporary variable, and do the
11618 -- change of representation assignment into that temporary variable.
11619 -- The conversion is then replaced by a reference to this variable.
11620
11621 else
11622 Cons := No_List;
11623
685094bf 11624 -- If type is unconstrained we have to add a constraint, copied
356ffab8 11625 -- from the actual value of the left-hand side.
70482933
RK
11626
11627 if not Is_Constrained (Target_Type) then
11628 if Has_Discriminants (Operand_Type) then
fbf5a39b 11629
7c15c6dd
AC
11630 -- A change of representation can only apply to untagged
11631 -- types. We need to build the constraint that applies to
11632 -- the target type, using the constraints of the operand.
11633 -- The analysis is complicated if there are both inherited
11634 -- discriminants and constrained discriminants.
11635 -- We iterate over the discriminants of the target, and
11636 -- find the discriminant of the same name:
fbf5a39b 11637
7c15c6dd
AC
11638 -- a) If there is a corresponding discriminant in the object
11639 -- then the value is a selected component of the operand.
11640
11641 -- b) Otherwise the value of a constrained discriminant is
11642 -- found in the stored constraint of the operand.
11643
11644 declare
11645 Stored : constant Elist_Id :=
a4f4dbdb 11646 Stored_Constraint (Operand_Type);
7c15c6dd
AC
11647
11648 Elmt : Elmt_Id;
11649
11650 Disc_O : Entity_Id;
11651 -- Discriminant of the operand type. Its value in the
a4f4dbdb 11652 -- object is captured in a selected component.
7c15c6dd
AC
11653
11654 Disc_S : Entity_Id;
11655 -- Stored discriminant of the operand. If present, it
11656 -- corresponds to a constrained discriminant of the
11657 -- parent type.
11658
11659 Disc_T : Entity_Id;
11660 -- Discriminant of the target type
11661
11662 begin
11663 Disc_T := First_Discriminant (Target_Type);
11664 Disc_O := First_Discriminant (Operand_Type);
11665 Disc_S := First_Stored_Discriminant (Operand_Type);
11666
11667 if Present (Stored) then
11668 Elmt := First_Elmt (Stored);
5612989e
PMR
11669 else
11670 Elmt := No_Elmt; -- init to avoid warning
7c15c6dd
AC
11671 end if;
11672
11673 Cons := New_List;
11674 while Present (Disc_T) loop
11675 if Present (Disc_O)
11676 and then Chars (Disc_T) = Chars (Disc_O)
11677 then
11678 Append_To (Cons,
11679 Make_Selected_Component (Loc,
11680 Prefix =>
11681 Duplicate_Subexpr_Move_Checks (Operand),
a4f4dbdb 11682 Selector_Name =>
7c15c6dd
AC
11683 Make_Identifier (Loc, Chars (Disc_O))));
11684 Next_Discriminant (Disc_O);
11685
11686 elsif Present (Disc_S) then
11687 Append_To (Cons, New_Copy_Tree (Node (Elmt)));
11688 Next_Elmt (Elmt);
11689 end if;
11690
11691 Next_Discriminant (Disc_T);
11692 end loop;
11693 end;
70482933
RK
11694
11695 elsif Is_Array_Type (Operand_Type) then
11696 N_Ix := First_Index (Target_Type);
11697 Cons := New_List;
11698
11699 for J in 1 .. Number_Dimensions (Operand_Type) loop
11700
11701 -- We convert the bounds explicitly. We use an unchecked
11702 -- conversion because bounds checks are done elsewhere.
11703
11704 Append_To (Cons,
11705 Make_Range (Loc,
a4f4dbdb 11706 Low_Bound =>
70482933
RK
11707 Unchecked_Convert_To (Etype (N_Ix),
11708 Make_Attribute_Reference (Loc,
a4f4dbdb 11709 Prefix =>
fbf5a39b 11710 Duplicate_Subexpr_No_Checks
70482933
RK
11711 (Operand, Name_Req => True),
11712 Attribute_Name => Name_First,
11713 Expressions => New_List (
11714 Make_Integer_Literal (Loc, J)))),
11715
11716 High_Bound =>
11717 Unchecked_Convert_To (Etype (N_Ix),
11718 Make_Attribute_Reference (Loc,
a4f4dbdb 11719 Prefix =>
fbf5a39b 11720 Duplicate_Subexpr_No_Checks
70482933
RK
11721 (Operand, Name_Req => True),
11722 Attribute_Name => Name_Last,
11723 Expressions => New_List (
11724 Make_Integer_Literal (Loc, J))))));
11725
11726 Next_Index (N_Ix);
11727 end loop;
11728 end if;
11729 end if;
11730
11731 Odef := New_Occurrence_Of (Target_Type, Loc);
11732
11733 if Present (Cons) then
11734 Odef :=
11735 Make_Subtype_Indication (Loc,
11736 Subtype_Mark => Odef,
a4f4dbdb 11737 Constraint =>
70482933
RK
11738 Make_Index_Or_Discriminant_Constraint (Loc,
11739 Constraints => Cons));
11740 end if;
11741
191fcb3a 11742 Temp := Make_Temporary (Loc, 'C');
70482933
RK
11743 Decl :=
11744 Make_Object_Declaration (Loc,
11745 Defining_Identifier => Temp,
11746 Object_Definition => Odef);
11747
11748 Set_No_Initialization (Decl, True);
11749
11750 -- Insert required actions. It is essential to suppress checks
11751 -- since we have suppressed default initialization, which means
11752 -- that the variable we create may have no discriminants.
11753
11754 Insert_Actions (N,
11755 New_List (
11756 Decl,
11757 Make_Assignment_Statement (Loc,
a4f4dbdb 11758 Name => New_Occurrence_Of (Temp, Loc),
70482933
RK
11759 Expression => Relocate_Node (N))),
11760 Suppress => All_Checks);
11761
11762 Rewrite (N, New_Occurrence_Of (Temp, Loc));
11763 return;
11764 end if;
11765 end Handle_Changed_Representation;
11766
426908f8
RD
11767 -------------------------------
11768 -- Raise_Accessibility_Error --
11769 -------------------------------
11770
11771 procedure Raise_Accessibility_Error is
11772 begin
43417b90 11773 Error_Msg_Warn := SPARK_Mode /= On;
426908f8
RD
11774 Rewrite (N,
11775 Make_Raise_Program_Error (Sloc (N),
11776 Reason => PE_Accessibility_Check_Failed));
11777 Set_Etype (N, Target_Type);
11778
4a28b181
AC
11779 Error_Msg_N ("<<accessibility check failure", N);
11780 Error_Msg_NE ("\<<& [", N, Standard_Program_Error);
426908f8
RD
11781 end Raise_Accessibility_Error;
11782
70482933
RK
11783 ----------------------
11784 -- Real_Range_Check --
11785 ----------------------
11786
685094bf
RD
11787 -- Case of conversions to floating-point or fixed-point. If range checks
11788 -- are enabled and the target type has a range constraint, we convert:
70482933
RK
11789
11790 -- typ (x)
11791
11792 -- to
11793
11794 -- Tnn : typ'Base := typ'Base (x);
11795 -- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
4e896dad 11796 -- typ (Tnn)
70482933 11797
685094bf
RD
11798 -- This is necessary when there is a conversion of integer to float or
11799 -- to fixed-point to ensure that the correct checks are made. It is not
4e896dad
EB
11800 -- necessary for the float-to-float case where it is enough to just set
11801 -- the Do_Range_Check flag on the expression.
fbf5a39b 11802
70482933
RK
11803 procedure Real_Range_Check is
11804 Btyp : constant Entity_Id := Base_Type (Target_Type);
11805 Lo : constant Node_Id := Type_Low_Bound (Target_Type);
11806 Hi : constant Node_Id := Type_High_Bound (Target_Type);
a98217be
ES
11807
11808 Conv : Node_Id;
a98217be
ES
11809 Hi_Arg : Node_Id;
11810 Hi_Val : Node_Id;
f537fc00
HK
11811 Lo_Arg : Node_Id;
11812 Lo_Val : Node_Id;
4e896dad 11813 Expr : Entity_Id;
a98217be 11814 Tnn : Entity_Id;
70482933
RK
11815
11816 begin
17ea7fad 11817 -- Nothing more to do if conversion was rewritten
70482933
RK
11818
11819 if Nkind (N) /= N_Type_Conversion then
11820 return;
11821 end if;
11822
4e896dad
EB
11823 Expr := Expression (N);
11824
17ea7fad 11825 -- Clear the Do_Range_Check flag on Expr
4e896dad
EB
11826
11827 Set_Do_Range_Check (Expr, False);
11828
685094bf
RD
11829 -- Nothing to do if range checks suppressed, or target has the same
11830 -- range as the base type (or is the base type).
70482933
RK
11831
11832 if Range_Checks_Suppressed (Target_Type)
533369aa 11833 or else (Lo = Type_Low_Bound (Btyp)
70482933
RK
11834 and then
11835 Hi = Type_High_Bound (Btyp))
11836 then
11837 return;
11838 end if;
11839
685094bf
RD
11840 -- Nothing to do if expression is an entity on which checks have been
11841 -- suppressed.
70482933 11842
4e896dad
EB
11843 if Is_Entity_Name (Expr)
11844 and then Range_Checks_Suppressed (Entity (Expr))
11845 then
11846 return;
11847 end if;
11848
11849 -- Nothing to do if expression was rewritten into a float-to-float
31fde973 11850 -- conversion, since this kind of conversion is handled elsewhere.
4e896dad
EB
11851
11852 if Is_Floating_Point_Type (Etype (Expr))
11853 and then Is_Floating_Point_Type (Target_Type)
fbf5a39b
AC
11854 then
11855 return;
11856 end if;
11857
685094bf
RD
11858 -- Nothing to do if bounds are all static and we can tell that the
11859 -- expression is within the bounds of the target. Note that if the
11860 -- operand is of an unconstrained floating-point type, then we do
11861 -- not trust it to be in range (might be infinite)
fbf5a39b
AC
11862
11863 declare
4e896dad
EB
11864 S_Lo : constant Node_Id := Type_Low_Bound (Etype (Expr));
11865 S_Hi : constant Node_Id := Type_High_Bound (Etype (Expr));
fbf5a39b
AC
11866
11867 begin
4e896dad
EB
11868 if (not Is_Floating_Point_Type (Etype (Expr))
11869 or else Is_Constrained (Etype (Expr)))
fbf5a39b
AC
11870 and then Compile_Time_Known_Value (S_Lo)
11871 and then Compile_Time_Known_Value (S_Hi)
11872 and then Compile_Time_Known_Value (Hi)
11873 and then Compile_Time_Known_Value (Lo)
11874 then
11875 declare
11876 D_Lov : constant Ureal := Expr_Value_R (Lo);
11877 D_Hiv : constant Ureal := Expr_Value_R (Hi);
11878 S_Lov : Ureal;
11879 S_Hiv : Ureal;
11880
11881 begin
4e896dad 11882 if Is_Real_Type (Etype (Expr)) then
fbf5a39b
AC
11883 S_Lov := Expr_Value_R (S_Lo);
11884 S_Hiv := Expr_Value_R (S_Hi);
11885 else
11886 S_Lov := UR_From_Uint (Expr_Value (S_Lo));
11887 S_Hiv := UR_From_Uint (Expr_Value (S_Hi));
11888 end if;
11889
11890 if D_Hiv > D_Lov
11891 and then S_Lov >= D_Lov
11892 and then S_Hiv <= D_Hiv
11893 then
fbf5a39b
AC
11894 return;
11895 end if;
11896 end;
11897 end if;
11898 end;
11899
fbf5a39b 11900 -- Otherwise rewrite the conversion as described above
70482933 11901
4e896dad 11902 Conv := Convert_To (Btyp, Expr);
8113b0c7 11903
4e896dad
EB
11904 -- If a conversion is necessary, then copy the specific flags from
11905 -- the original one and also move the Do_Overflow_Check flag since
11906 -- this new conversion is to the base type.
70482933 11907
4e896dad
EB
11908 if Nkind (Conv) = N_Type_Conversion then
11909 Set_Conversion_OK (Conv, Conversion_OK (N));
11910 Set_Float_Truncate (Conv, Float_Truncate (N));
11911 Set_Rounded_Result (Conv, Rounded_Result (N));
70482933 11912
4e896dad
EB
11913 if Do_Overflow_Check (N) then
11914 Set_Do_Overflow_Check (Conv);
11915 Set_Do_Overflow_Check (N, False);
11916 end if;
70482933
RK
11917 end if;
11918
191fcb3a 11919 Tnn := Make_Temporary (Loc, 'T', Conv);
70482933 11920
a98217be
ES
11921 -- For a conversion from Float to Fixed where the bounds of the
11922 -- fixed-point type are static, we can obtain a more accurate
11923 -- fixed-point value by converting the result of the floating-
11924 -- point expression to an appropriate integer type, and then
11925 -- performing an unchecked conversion to the target fixed-point
11926 -- type. The range check can then use the corresponding integer
11927 -- value of the bounds instead of requiring further conversions.
11928 -- This preserves the identity:
11929
11930 -- Fix_Val = Fixed_Type (Float_Type (Fix_Val))
11931
11932 -- which used to fail when Fix_Val was a bound of the type and
11933 -- the 'Small was not a representable number.
11934 -- This transformation requires an integer type large enough to
8d87bb8f 11935 -- accommodate a fixed-point value.
a98217be
ES
11936
11937 if Is_Ordinary_Fixed_Point_Type (Target_Type)
4e896dad 11938 and then Is_Floating_Point_Type (Etype (Expr))
8d87bb8f 11939 and then RM_Size (Btyp) <= System_Max_Integer_Size
a98217be
ES
11940 and then Nkind (Lo) = N_Real_Literal
11941 and then Nkind (Hi) = N_Real_Literal
11942 then
a98217be 11943 declare
4e896dad 11944 Expr_Id : constant Entity_Id := Make_Temporary (Loc, 'T', Conv);
8d87bb8f
EB
11945 Int_Typ : constant Entity_Id :=
11946 Small_Integer_Type_For (RM_Size (Btyp), False);
a98217be
ES
11947
11948 begin
04920bb6 11949 -- Generate a temporary with the integer value. Required in the
4e896dad 11950 -- CCG compiler to ensure that run-time checks reference this
04920bb6 11951 -- integer expression (instead of the resulting fixed-point
4e896dad 11952 -- value because fixed-point values are handled by means of
04920bb6
JM
11953 -- unsigned integer types).
11954
11955 Insert_Action (N,
11956 Make_Object_Declaration (Loc,
11957 Defining_Identifier => Expr_Id,
8d87bb8f 11958 Object_Definition => New_Occurrence_Of (Int_Typ, Loc),
04920bb6
JM
11959 Constant_Present => True,
11960 Expression =>
8d87bb8f 11961 Convert_To (Int_Typ, Expression (Conv))));
04920bb6 11962
a98217be
ES
11963 -- Create integer objects for range checking of result.
11964
f537fc00
HK
11965 Lo_Arg :=
11966 Unchecked_Convert_To
8d87bb8f 11967 (Int_Typ, New_Occurrence_Of (Expr_Id, Loc));
f537fc00
HK
11968
11969 Lo_Val :=
11970 Make_Integer_Literal (Loc, Corresponding_Integer_Value (Lo));
a98217be 11971
f537fc00
HK
11972 Hi_Arg :=
11973 Unchecked_Convert_To
8d87bb8f 11974 (Int_Typ, New_Occurrence_Of (Expr_Id, Loc));
f537fc00
HK
11975
11976 Hi_Val :=
11977 Make_Integer_Literal (Loc, Corresponding_Integer_Value (Hi));
a98217be
ES
11978
11979 -- Rewrite conversion as an integer conversion of the
11980 -- original floating-point expression, followed by an
11981 -- unchecked conversion to the target fixed-point type.
11982
f537fc00
HK
11983 Conv :=
11984 Make_Unchecked_Type_Conversion (Loc,
11985 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
11986 Expression => New_Occurrence_Of (Expr_Id, Loc));
a98217be
ES
11987 end;
11988
f537fc00 11989 -- All other conversions
a98217be 11990
f537fc00 11991 else
a98217be 11992 Lo_Arg := New_Occurrence_Of (Tnn, Loc);
f537fc00
HK
11993 Lo_Val :=
11994 Make_Attribute_Reference (Loc,
11995 Prefix => New_Occurrence_Of (Target_Type, Loc),
11996 Attribute_Name => Name_First);
a98217be
ES
11997
11998 Hi_Arg := New_Occurrence_Of (Tnn, Loc);
f537fc00
HK
11999 Hi_Val :=
12000 Make_Attribute_Reference (Loc,
12001 Prefix => New_Occurrence_Of (Target_Type, Loc),
12002 Attribute_Name => Name_Last);
a98217be
ES
12003 end if;
12004
4e896dad
EB
12005 -- Build code for range checking. Note that checks are suppressed
12006 -- here since we don't want a recursive range check popping up.
a98217be 12007
70482933
RK
12008 Insert_Actions (N, New_List (
12009 Make_Object_Declaration (Loc,
12010 Defining_Identifier => Tnn,
12011 Object_Definition => New_Occurrence_Of (Btyp, Loc),
0ac2a660
AC
12012 Constant_Present => True,
12013 Expression => Conv),
f537fc00 12014
70482933 12015 Make_Raise_Constraint_Error (Loc,
f537fc00
HK
12016 Condition =>
12017 Make_Or_Else (Loc,
12018 Left_Opnd =>
12019 Make_Op_Lt (Loc,
12020 Left_Opnd => Lo_Arg,
12021 Right_Opnd => Lo_Val),
70482933 12022
07fc65c4
GB
12023 Right_Opnd =>
12024 Make_Op_Gt (Loc,
a98217be
ES
12025 Left_Opnd => Hi_Arg,
12026 Right_Opnd => Hi_Val)),
4e896dad
EB
12027 Reason => CE_Range_Check_Failed)),
12028 Suppress => All_Checks);
70482933 12029
4e896dad 12030 Rewrite (Expr, New_Occurrence_Of (Tnn, Loc));
70482933
RK
12031 end Real_Range_Check;
12032
d15f9422
AC
12033 -----------------------------
12034 -- Has_Extra_Accessibility --
12035 -----------------------------
12036
f537fc00
HK
12037 -- Returns true for a formal of an anonymous access type or for an Ada
12038 -- 2012-style stand-alone object of an anonymous access type.
d15f9422
AC
12039
12040 function Has_Extra_Accessibility (Id : Entity_Id) return Boolean is
12041 begin
4a08c95c 12042 if Is_Formal (Id) or else Ekind (Id) in E_Constant | E_Variable then
d15f9422
AC
12043 return Present (Effective_Extra_Accessibility (Id));
12044 else
12045 return False;
12046 end if;
12047 end Has_Extra_Accessibility;
12048
1a0d2909
JS
12049 ----------------------------------------
12050 -- Statically_Deeper_Relation_Applies --
12051 ----------------------------------------
12052
12053 function Statically_Deeper_Relation_Applies (Targ_Typ : Entity_Id)
12054 return Boolean
12055 is
12056 begin
12057 -- The case where the target type is an anonymous access type is
12058 -- ignored since they have different semantics and get covered by
12059 -- various runtime checks depending on context.
12060
12061 -- Note, the current implementation of this predicate is incomplete
12062 -- and doesn't fully reflect the rules given in RM 3.10.2 (19) and
12063 -- (19.1) ???
12064
12065 return Ekind (Targ_Typ) /= E_Anonymous_Access_Type;
12066 end Statically_Deeper_Relation_Applies;
12067
70482933
RK
12068 -- Start of processing for Expand_N_Type_Conversion
12069
12070 begin
83851b23 12071 -- First remove check marks put by the semantic analysis on the type
b2502161
AC
12072 -- conversion between array types. We need these checks, and they will
12073 -- be generated by this expansion routine, but we do not depend on these
12074 -- flags being set, and since we do intend to expand the checks in the
12075 -- front end, we don't want them on the tree passed to the back end.
83851b23
AC
12076
12077 if Is_Array_Type (Target_Type) then
12078 if Is_Constrained (Target_Type) then
12079 Set_Do_Length_Check (N, False);
12080 else
12081 Set_Do_Range_Check (Operand, False);
12082 end if;
12083 end if;
12084
685094bf 12085 -- Nothing at all to do if conversion is to the identical type so remove
76efd572 12086 -- the conversion completely, it is useless, except that it may carry
17ea7fad 12087 -- an Assignment_OK attribute, which must be propagated to the operand
84c54629 12088 -- and the Do_Range_Check flag on the operand must be cleared, if any.
70482933
RK
12089
12090 if Operand_Type = Target_Type then
7b00e31d
AC
12091 if Assignment_OK (N) then
12092 Set_Assignment_OK (Operand);
12093 end if;
12094
84c54629 12095 Set_Do_Range_Check (Operand, False);
17ea7fad 12096
84c54629 12097 Rewrite (N, Relocate_Node (Operand));
17ea7fad 12098
e606088a 12099 goto Done;
70482933
RK
12100 end if;
12101
685094bf
RD
12102 -- Nothing to do if this is the second argument of read. This is a
12103 -- "backwards" conversion that will be handled by the specialized code
12104 -- in attribute processing.
70482933
RK
12105
12106 if Nkind (Parent (N)) = N_Attribute_Reference
12107 and then Attribute_Name (Parent (N)) = Name_Read
12108 and then Next (First (Expressions (Parent (N)))) = N
12109 then
e606088a
AC
12110 goto Done;
12111 end if;
12112
12113 -- Check for case of converting to a type that has an invariant
d89ce432
AC
12114 -- associated with it. This requires an invariant check. We insert
12115 -- a call:
e606088a 12116
d89ce432 12117 -- invariant_check (typ (expr))
e606088a 12118
d89ce432
AC
12119 -- in the code, after removing side effects from the expression.
12120 -- This is clearer than replacing the conversion into an expression
12121 -- with actions, because the context may impose additional actions
12122 -- (tag checks, membership tests, etc.) that conflict with this
12123 -- rewriting (used previously).
e606088a
AC
12124
12125 -- Note: the Comes_From_Source check, and then the resetting of this
12126 -- flag prevents what would otherwise be an infinite recursion.
12127
fd0ff1cf
RD
12128 if Has_Invariants (Target_Type)
12129 and then Present (Invariant_Procedure (Target_Type))
e606088a
AC
12130 and then Comes_From_Source (N)
12131 then
12132 Set_Comes_From_Source (N, False);
d89ce432
AC
12133 Remove_Side_Effects (N);
12134 Insert_Action (N, Make_Invariant_Call (Duplicate_Subexpr (N)));
e606088a 12135 goto Done;
7e06a62f
GD
12136
12137 -- AI12-0042: For a view conversion to a class-wide type occurring
12138 -- within the immediate scope of T, from a specific type that is
12139 -- a descendant of T (including T itself), an invariant check is
12140 -- performed on the part of the object that is of type T. (We don't
12141 -- need to explicitly check for the operand type being a descendant,
12142 -- just that it's a specific type, because the conversion would be
12143 -- illegal if it's specific and not a descendant -- downward conversion
12144 -- is not allowed).
12145
12146 elsif Is_Class_Wide_Type (Target_Type)
12147 and then not Is_Class_Wide_Type (Etype (Expression (N)))
12148 and then Present (Invariant_Procedure (Root_Type (Target_Type)))
12149 and then Comes_From_Source (N)
12150 and then Within_Scope (Find_Enclosing_Scope (N), Scope (Target_Type))
12151 then
12152 Remove_Side_Effects (N);
12153
12154 -- Perform the invariant check on a conversion to the class-wide
12155 -- type's root type.
12156
12157 declare
12158 Root_Conv : constant Node_Id :=
12159 Make_Type_Conversion (Loc,
12160 Subtype_Mark =>
12161 New_Occurrence_Of (Root_Type (Target_Type), Loc),
12162 Expression => Duplicate_Subexpr (Expression (N)));
12163 begin
12164 Set_Etype (Root_Conv, Root_Type (Target_Type));
12165
12166 Insert_Action (N, Make_Invariant_Call (Root_Conv));
12167 goto Done;
12168 end;
70482933
RK
12169 end if;
12170
12171 -- Here if we may need to expand conversion
12172
eaa826f8
RD
12173 -- If the operand of the type conversion is an arithmetic operation on
12174 -- signed integers, and the based type of the signed integer type in
12175 -- question is smaller than Standard.Integer, we promote both of the
12176 -- operands to type Integer.
12177
12178 -- For example, if we have
12179
12180 -- target-type (opnd1 + opnd2)
12181
12182 -- and opnd1 and opnd2 are of type short integer, then we rewrite
12183 -- this as:
12184
12185 -- target-type (integer(opnd1) + integer(opnd2))
12186
12187 -- We do this because we are always allowed to compute in a larger type
12188 -- if we do the right thing with the result, and in this case we are
12189 -- going to do a conversion which will do an appropriate check to make
12190 -- sure that things are in range of the target type in any case. This
12191 -- avoids some unnecessary intermediate overflows.
12192
dfcfdc0a
AC
12193 -- We might consider a similar transformation in the case where the
12194 -- target is a real type or a 64-bit integer type, and the operand
12195 -- is an arithmetic operation using a 32-bit integer type. However,
12196 -- we do not bother with this case, because it could cause significant
308e6f3a 12197 -- inefficiencies on 32-bit machines. On a 64-bit machine it would be
dfcfdc0a
AC
12198 -- much cheaper, but we don't want different behavior on 32-bit and
12199 -- 64-bit machines. Note that the exclusion of the 64-bit case also
12200 -- handles the configurable run-time cases where 64-bit arithmetic
12201 -- may simply be unavailable.
eaa826f8
RD
12202
12203 -- Note: this circuit is partially redundant with respect to the circuit
12204 -- in Checks.Apply_Arithmetic_Overflow_Check, but we catch more cases in
12205 -- the processing here. Also we still need the Checks circuit, since we
12206 -- have to be sure not to generate junk overflow checks in the first
17ea7fad 12207 -- place, since it would be tricky to remove them here.
eaa826f8 12208
fdfcc663 12209 if Integer_Promotion_Possible (N) then
eaa826f8 12210
fdfcc663 12211 -- All conditions met, go ahead with transformation
eaa826f8 12212
fdfcc663
AC
12213 declare
12214 Opnd : Node_Id;
12215 L, R : Node_Id;
dfcfdc0a 12216
fdfcc663 12217 begin
5f3f175d 12218 Opnd := New_Op_Node (Nkind (Operand), Loc);
6c8e4f7e
EB
12219
12220 R := Convert_To (Standard_Integer, Right_Opnd (Operand));
5f3f175d 12221 Set_Right_Opnd (Opnd, R);
eaa826f8 12222
5f3f175d 12223 if Nkind (Operand) in N_Binary_Op then
6c8e4f7e 12224 L := Convert_To (Standard_Integer, Left_Opnd (Operand));
5f3f175d
AC
12225 Set_Left_Opnd (Opnd, L);
12226 end if;
eaa826f8 12227
5f3f175d
AC
12228 Rewrite (N,
12229 Make_Type_Conversion (Loc,
12230 Subtype_Mark => Relocate_Node (Subtype_Mark (N)),
12231 Expression => Opnd));
dfcfdc0a 12232
5f3f175d 12233 Analyze_And_Resolve (N, Target_Type);
e606088a 12234 goto Done;
fdfcc663
AC
12235 end;
12236 end if;
eaa826f8 12237
2e8ee0a3
EB
12238 -- If the conversion is from Universal_Integer and requires an overflow
12239 -- check, try to do an intermediate conversion to a narrower type first
12240 -- without overflow check, in order to avoid doing the overflow check
12241 -- in Universal_Integer, which can be a very large type.
12242
12243 if Operand_Type = Universal_Integer and then Do_Overflow_Check (N) then
12244 declare
12245 Lo, Hi, Siz : Uint;
12246 OK : Boolean;
12247 Typ : Entity_Id;
12248
12249 begin
12250 Determine_Range (Operand, OK, Lo, Hi, Assume_Valid => True);
12251
12252 if OK then
12253 Siz := Get_Size_For_Range (Lo, Hi);
12254
12255 -- We use the base type instead of the first subtype because
12256 -- overflow checks are done in the base type, so this avoids
12257 -- the need for useless conversions.
12258
12259 if Siz < System_Max_Integer_Size then
12260 Typ := Etype (Integer_Type_For (Siz, Uns => False));
12261
12262 Convert_To_And_Rewrite (Typ, Operand);
12263 Analyze_And_Resolve
12264 (Operand, Typ, Suppress => Overflow_Check);
12265
12266 Analyze_And_Resolve (N, Target_Type);
12267 goto Done;
12268 end if;
12269 end if;
12270 end;
12271 end if;
12272
f82944b7
JM
12273 -- Do validity check if validity checking operands
12274
533369aa 12275 if Validity_Checks_On and Validity_Check_Operands then
f82944b7
JM
12276 Ensure_Valid (Operand);
12277 end if;
12278
70482933
RK
12279 -- Special case of converting from non-standard boolean type
12280
12281 if Is_Boolean_Type (Operand_Type)
12282 and then (Nonzero_Is_True (Operand_Type))
12283 then
12284 Adjust_Condition (Operand);
12285 Set_Etype (Operand, Standard_Boolean);
12286 Operand_Type := Standard_Boolean;
12287 end if;
12288
12289 -- Case of converting to an access type
12290
12291 if Is_Access_Type (Target_Type) then
1b2f53bb
JS
12292 -- In terms of accessibility rules, an anonymous access discriminant
12293 -- is not considered separate from its parent object.
12294
12295 if Nkind (Operand) = N_Selected_Component
12296 and then Ekind (Entity (Selector_Name (Operand))) = E_Discriminant
12297 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
12298 then
12299 Operand_Acc := Original_Node (Prefix (Operand));
12300 end if;
70482933 12301
ca0b6141 12302 -- If this type conversion was internally generated by the front end
904a2ae4 12303 -- to displace the pointer to the object to reference an interface
ca0b6141 12304 -- type and the original node was an Unrestricted_Access attribute,
904a2ae4
AC
12305 -- then skip applying accessibility checks (because, according to the
12306 -- GNAT Reference Manual, this attribute is similar to 'Access except
12307 -- that all accessibility and aliased view checks are omitted).
12308
12309 if not Comes_From_Source (N)
12310 and then Is_Interface (Designated_Type (Target_Type))
12311 and then Nkind (Original_Node (N)) = N_Attribute_Reference
0bcee275
AC
12312 and then Attribute_Name (Original_Node (N)) =
12313 Name_Unrestricted_Access
904a2ae4
AC
12314 then
12315 null;
12316
d766cee3
RD
12317 -- Apply an accessibility check when the conversion operand is an
12318 -- access parameter (or a renaming thereof), unless conversion was
6a237c45 12319 -- expanded from an Unchecked_ or Unrestricted_Access attribute,
683af98c
AC
12320 -- or for the actual of a class-wide interface parameter. Note that
12321 -- other checks may still need to be applied below (such as tagged
12322 -- type checks).
70482933 12323
1b2f53bb
JS
12324 elsif Is_Entity_Name (Operand_Acc)
12325 and then Has_Extra_Accessibility (Entity (Operand_Acc))
12326 and then Ekind (Etype (Operand_Acc)) = E_Anonymous_Access_Type
d766cee3
RD
12327 and then (Nkind (Original_Node (N)) /= N_Attribute_Reference
12328 or else Attribute_Name (Original_Node (N)) = Name_Access)
70482933 12329 then
6a237c45 12330 if not Comes_From_Source (N)
4a08c95c
AC
12331 and then Nkind (Parent (N)) in N_Function_Call
12332 | N_Parameter_Association
12333 | N_Procedure_Call_Statement
6a237c45
AC
12334 and then Is_Interface (Designated_Type (Target_Type))
12335 and then Is_Class_Wide_Type (Designated_Type (Target_Type))
12336 then
12337 null;
12338
12339 else
12340 Apply_Accessibility_Check
b6735a10 12341 (Operand, Target_Type, Insert_Node => Operand);
6a237c45 12342 end if;
70482933 12343
e84e11ba 12344 -- If the level of the operand type is statically deeper than the
685094bf
RD
12345 -- level of the target type, then force Program_Error. Note that this
12346 -- can only occur for cases where the attribute is within the body of
6c56d9b8
AC
12347 -- an instantiation, otherwise the conversion will already have been
12348 -- rejected as illegal.
12349
12350 -- Note: warnings are issued by the analyzer for the instance cases
70482933
RK
12351
12352 elsif In_Instance_Body
1a0d2909 12353 and then Statically_Deeper_Relation_Applies (Target_Type)
ad5edba5
AC
12354 and then
12355 Type_Access_Level (Operand_Type) > Type_Access_Level (Target_Type)
70482933 12356 then
426908f8 12357 Raise_Accessibility_Error;
91669e7e 12358 goto Done;
70482933 12359
685094bf
RD
12360 -- When the operand is a selected access discriminant the check needs
12361 -- to be made against the level of the object denoted by the prefix
12362 -- of the selected name. Force Program_Error for this case as well
12363 -- (this accessibility violation can only happen if within the body
12364 -- of an instantiation).
70482933
RK
12365
12366 elsif In_Instance_Body
12367 and then Ekind (Operand_Type) = E_Anonymous_Access_Type
12368 and then Nkind (Operand) = N_Selected_Component
ec98bb7d 12369 and then Ekind (Entity (Selector_Name (Operand))) = E_Discriminant
66e97274
JS
12370 and then Static_Accessibility_Level (Operand, Zero_On_Dynamic_Level)
12371 > Type_Access_Level (Target_Type)
70482933 12372 then
426908f8 12373 Raise_Accessibility_Error;
e606088a 12374 goto Done;
70482933
RK
12375 end if;
12376 end if;
12377
12378 -- Case of conversions of tagged types and access to tagged types
12379
685094bf
RD
12380 -- When needed, that is to say when the expression is class-wide, Add
12381 -- runtime a tag check for (strict) downward conversion by using the
12382 -- membership test, generating:
70482933
RK
12383
12384 -- [constraint_error when Operand not in Target_Type'Class]
12385
12386 -- or in the access type case
12387
12388 -- [constraint_error
12389 -- when Operand /= null
12390 -- and then Operand.all not in
12391 -- Designated_Type (Target_Type)'Class]
12392
12393 if (Is_Access_Type (Target_Type)
12394 and then Is_Tagged_Type (Designated_Type (Target_Type)))
12395 or else Is_Tagged_Type (Target_Type)
12396 then
685094bf
RD
12397 -- Do not do any expansion in the access type case if the parent is a
12398 -- renaming, since this is an error situation which will be caught by
12399 -- Sem_Ch8, and the expansion can interfere with this error check.
70482933 12400
e7e4d230 12401 if Is_Access_Type (Target_Type) and then Is_Renamed_Object (N) then
e606088a 12402 goto Done;
70482933
RK
12403 end if;
12404
0669bebe 12405 -- Otherwise, proceed with processing tagged conversion
70482933 12406
e7e4d230 12407 Tagged_Conversion : declare
8cea7b64
HK
12408 Actual_Op_Typ : Entity_Id;
12409 Actual_Targ_Typ : Entity_Id;
8cea7b64 12410 Root_Op_Typ : Entity_Id;
70482933 12411
8cea7b64
HK
12412 procedure Make_Tag_Check (Targ_Typ : Entity_Id);
12413 -- Create a membership check to test whether Operand is a member
12414 -- of Targ_Typ. If the original Target_Type is an access, include
12415 -- a test for null value. The check is inserted at N.
12416
12417 --------------------
12418 -- Make_Tag_Check --
12419 --------------------
12420
12421 procedure Make_Tag_Check (Targ_Typ : Entity_Id) is
12422 Cond : Node_Id;
12423
12424 begin
12425 -- Generate:
12426 -- [Constraint_Error
12427 -- when Operand /= null
12428 -- and then Operand.all not in Targ_Typ]
12429
12430 if Is_Access_Type (Target_Type) then
12431 Cond :=
12432 Make_And_Then (Loc,
12433 Left_Opnd =>
12434 Make_Op_Ne (Loc,
12435 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
12436 Right_Opnd => Make_Null (Loc)),
12437
12438 Right_Opnd =>
12439 Make_Not_In (Loc,
12440 Left_Opnd =>
12441 Make_Explicit_Dereference (Loc,
12442 Prefix => Duplicate_Subexpr_No_Checks (Operand)),
e4494292 12443 Right_Opnd => New_Occurrence_Of (Targ_Typ, Loc)));
8cea7b64
HK
12444
12445 -- Generate:
12446 -- [Constraint_Error when Operand not in Targ_Typ]
12447
12448 else
12449 Cond :=
12450 Make_Not_In (Loc,
12451 Left_Opnd => Duplicate_Subexpr_No_Checks (Operand),
e4494292 12452 Right_Opnd => New_Occurrence_Of (Targ_Typ, Loc));
8cea7b64
HK
12453 end if;
12454
12455 Insert_Action (N,
12456 Make_Raise_Constraint_Error (Loc,
12457 Condition => Cond,
cf9a473e
AC
12458 Reason => CE_Tag_Check_Failed),
12459 Suppress => All_Checks);
8cea7b64
HK
12460 end Make_Tag_Check;
12461
e7e4d230 12462 -- Start of processing for Tagged_Conversion
70482933
RK
12463
12464 begin
9732e886 12465 -- Handle entities from the limited view
852dba80 12466
9732e886 12467 if Is_Access_Type (Operand_Type) then
852dba80
AC
12468 Actual_Op_Typ :=
12469 Available_View (Designated_Type (Operand_Type));
9732e886
JM
12470 else
12471 Actual_Op_Typ := Operand_Type;
12472 end if;
12473
12474 if Is_Access_Type (Target_Type) then
852dba80
AC
12475 Actual_Targ_Typ :=
12476 Available_View (Designated_Type (Target_Type));
70482933 12477 else
8cea7b64 12478 Actual_Targ_Typ := Target_Type;
70482933
RK
12479 end if;
12480
8cea7b64
HK
12481 Root_Op_Typ := Root_Type (Actual_Op_Typ);
12482
20b5d666
JM
12483 -- Ada 2005 (AI-251): Handle interface type conversion
12484
3cb9a885 12485 if Is_Interface (Actual_Op_Typ)
58b81ab0
AC
12486 or else
12487 Is_Interface (Actual_Targ_Typ)
3cb9a885 12488 then
f6f4d8d4 12489 Expand_Interface_Conversion (N);
e606088a 12490 goto Done;
20b5d666
JM
12491 end if;
12492
c5a913d3 12493 -- Create a runtime tag check for a downward CW type conversion
70482933 12494
c5a913d3
EB
12495 if Is_Class_Wide_Type (Actual_Op_Typ)
12496 and then Actual_Op_Typ /= Actual_Targ_Typ
12497 and then Root_Op_Typ /= Actual_Targ_Typ
12498 and then Is_Ancestor
12499 (Root_Op_Typ, Actual_Targ_Typ, Use_Full_View => True)
12500 and then not Tag_Checks_Suppressed (Actual_Targ_Typ)
12501 then
12502 declare
12503 Conv : Node_Id;
12504 begin
8cea7b64 12505 Make_Tag_Check (Class_Wide_Type (Actual_Targ_Typ));
c5a913d3
EB
12506 Conv :=
12507 Make_Unchecked_Type_Conversion (Loc,
12508 Subtype_Mark => New_Occurrence_Of (Target_Type, Loc),
12509 Expression => Relocate_Node (Expression (N)));
12510 Rewrite (N, Conv);
12511 Analyze_And_Resolve (N, Target_Type);
12512 end;
70482933 12513 end if;
e7e4d230 12514 end Tagged_Conversion;
70482933
RK
12515
12516 -- Case of other access type conversions
12517
12518 elsif Is_Access_Type (Target_Type) then
12519 Apply_Constraint_Check (Operand, Target_Type);
12520
12521 -- Case of conversions from a fixed-point type
12522
685094bf
RD
12523 -- These conversions require special expansion and processing, found in
12524 -- the Exp_Fixd package. We ignore cases where Conversion_OK is set,
12525 -- since from a semantic point of view, these are simple integer
17ea7fad
AC
12526 -- conversions, which do not need further processing except for the
12527 -- generation of range checks, which is performed at the end of this
12528 -- procedure.
70482933
RK
12529
12530 elsif Is_Fixed_Point_Type (Operand_Type)
12531 and then not Conversion_OK (N)
12532 then
12533 -- We should never see universal fixed at this case, since the
12534 -- expansion of the constituent divide or multiply should have
12535 -- eliminated the explicit mention of universal fixed.
12536
12537 pragma Assert (Operand_Type /= Universal_Fixed);
12538
685094bf
RD
12539 -- Check for special case of the conversion to universal real that
12540 -- occurs as a result of the use of a round attribute. In this case,
12541 -- the real type for the conversion is taken from the target type of
12542 -- the Round attribute and the result must be marked as rounded.
70482933
RK
12543
12544 if Target_Type = Universal_Real
12545 and then Nkind (Parent (N)) = N_Attribute_Reference
12546 and then Attribute_Name (Parent (N)) = Name_Round
12547 then
70482933 12548 Set_Etype (N, Etype (Parent (N)));
8113b0c7 12549 Target_Type := Etype (N);
32543637 12550 Set_Rounded_Result (N);
70482933
RK
12551 end if;
12552
8113b0c7
EB
12553 if Is_Fixed_Point_Type (Target_Type) then
12554 Expand_Convert_Fixed_To_Fixed (N);
8113b0c7
EB
12555 elsif Is_Integer_Type (Target_Type) then
12556 Expand_Convert_Fixed_To_Integer (N);
8113b0c7
EB
12557 else
12558 pragma Assert (Is_Floating_Point_Type (Target_Type));
12559 Expand_Convert_Fixed_To_Float (N);
70482933
RK
12560 end if;
12561
12562 -- Case of conversions to a fixed-point type
12563
685094bf
RD
12564 -- These conversions require special expansion and processing, found in
12565 -- the Exp_Fixd package. Again, ignore cases where Conversion_OK is set,
12566 -- since from a semantic point of view, these are simple integer
12567 -- conversions, which do not need further processing.
70482933
RK
12568
12569 elsif Is_Fixed_Point_Type (Target_Type)
12570 and then not Conversion_OK (N)
12571 then
12572 if Is_Integer_Type (Operand_Type) then
12573 Expand_Convert_Integer_To_Fixed (N);
70482933
RK
12574 else
12575 pragma Assert (Is_Floating_Point_Type (Operand_Type));
12576 Expand_Convert_Float_To_Fixed (N);
70482933
RK
12577 end if;
12578
70482933
RK
12579 -- Case of array conversions
12580
685094bf
RD
12581 -- Expansion of array conversions, add required length/range checks but
12582 -- only do this if there is no change of representation. For handling of
12583 -- this case, see Handle_Changed_Representation.
70482933
RK
12584
12585 elsif Is_Array_Type (Target_Type) then
70482933
RK
12586 if Is_Constrained (Target_Type) then
12587 Apply_Length_Check (Operand, Target_Type);
12588 else
12589 Apply_Range_Check (Operand, Target_Type);
12590 end if;
12591
12592 Handle_Changed_Representation;
12593
12594 -- Case of conversions of discriminated types
12595
685094bf
RD
12596 -- Add required discriminant checks if target is constrained. Again this
12597 -- change is skipped if we have a change of representation.
70482933
RK
12598
12599 elsif Has_Discriminants (Target_Type)
12600 and then Is_Constrained (Target_Type)
12601 then
12602 Apply_Discriminant_Check (Operand, Target_Type);
12603 Handle_Changed_Representation;
12604
12605 -- Case of all other record conversions. The only processing required
12606 -- is to check for a change of representation requiring the special
12607 -- assignment processing.
12608
12609 elsif Is_Record_Type (Target_Type) then
5d09245e
AC
12610
12611 -- Ada 2005 (AI-216): Program_Error is raised when converting from
685094bf
RD
12612 -- a derived Unchecked_Union type to an unconstrained type that is
12613 -- not Unchecked_Union if the operand lacks inferable discriminants.
5d09245e
AC
12614
12615 if Is_Derived_Type (Operand_Type)
12616 and then Is_Unchecked_Union (Base_Type (Operand_Type))
12617 and then not Is_Constrained (Target_Type)
12618 and then not Is_Unchecked_Union (Base_Type (Target_Type))
12619 and then not Has_Inferable_Discriminants (Operand)
12620 then
685094bf 12621 -- To prevent Gigi from generating illegal code, we generate a
5d09245e 12622 -- Program_Error node, but we give it the target type of the
6cb3037c 12623 -- conversion (is this requirement documented somewhere ???)
5d09245e
AC
12624
12625 declare
12626 PE : constant Node_Id := Make_Raise_Program_Error (Loc,
12627 Reason => PE_Unchecked_Union_Restriction);
12628
12629 begin
12630 Set_Etype (PE, Target_Type);
12631 Rewrite (N, PE);
12632
12633 end;
12634 else
12635 Handle_Changed_Representation;
12636 end if;
70482933
RK
12637
12638 -- Case of conversions of enumeration types
12639
12640 elsif Is_Enumeration_Type (Target_Type) then
12641
12642 -- Special processing is required if there is a change of
e7e4d230 12643 -- representation (from enumeration representation clauses).
70482933 12644
3968b02a 12645 if not Has_Compatible_Representation (Target_Type, Operand_Type)
f193b29e
EB
12646 and then not Conversion_OK (N)
12647 then
70482933 12648
f193b29e 12649 -- Convert: x(y) to x'val (ytyp'pos (y))
70482933
RK
12650
12651 Rewrite (N,
1c66c4f5
AC
12652 Make_Attribute_Reference (Loc,
12653 Prefix => New_Occurrence_Of (Target_Type, Loc),
12654 Attribute_Name => Name_Val,
12655 Expressions => New_List (
12656 Make_Attribute_Reference (Loc,
12657 Prefix => New_Occurrence_Of (Operand_Type, Loc),
12658 Attribute_Name => Name_Pos,
12659 Expressions => New_List (Operand)))));
70482933
RK
12660
12661 Analyze_And_Resolve (N, Target_Type);
12662 end if;
70482933
RK
12663 end if;
12664
685094bf 12665 -- At this stage, either the conversion node has been transformed into
e7e4d230 12666 -- some other equivalent expression, or left as a conversion that can be
0964be07 12667 -- handled by Gigi.
70482933 12668
685094bf 12669 -- The only remaining step is to generate a range check if we still have
267c7ff6
EB
12670 -- a type conversion at this stage and Do_Range_Check is set. Note that
12671 -- we need to deal with at most 8 out of the 9 possible cases of numeric
12672 -- conversions here, because the float-to-integer case is entirely dealt
12673 -- with by Apply_Float_Conversion_Check.
fbf5a39b 12674
8113b0c7
EB
12675 if Nkind (N) = N_Type_Conversion
12676 and then Do_Range_Check (Expression (N))
12677 then
12678 -- Float-to-float conversions
fbf5a39b 12679
8113b0c7 12680 if Is_Floating_Point_Type (Target_Type)
f5655e4a 12681 and then Is_Floating_Point_Type (Etype (Expression (N)))
7b536495 12682 then
67460d45
EB
12683 -- Reset overflow flag, since the range check will include
12684 -- dealing with possible overflow, and generate the check.
12685
12686 Set_Do_Overflow_Check (N, False);
12687
8113b0c7
EB
12688 Generate_Range_Check
12689 (Expression (N), Target_Type, CE_Range_Check_Failed);
fbf5a39b 12690
8113b0c7
EB
12691 -- Discrete-to-discrete conversions or fixed-point-to-discrete
12692 -- conversions when Conversion_OK is set.
fbf5a39b 12693
8113b0c7
EB
12694 elsif Is_Discrete_Type (Target_Type)
12695 and then (Is_Discrete_Type (Etype (Expression (N)))
12696 or else (Is_Fixed_Point_Type (Etype (Expression (N)))
12697 and then Conversion_OK (N)))
12698 then
8113b0c7
EB
12699 -- If Address is either a source type or target type,
12700 -- suppress range check to avoid typing anomalies when
12701 -- it is a visible integer type.
7b536495 12702
8113b0c7
EB
12703 if Is_Descendant_Of_Address (Etype (Expression (N)))
12704 or else Is_Descendant_Of_Address (Target_Type)
12705 then
12706 Set_Do_Range_Check (Expression (N), False);
12707 else
12708 Discrete_Range_Check;
12709 end if;
7b536495 12710
8113b0c7 12711 -- Conversions to floating- or fixed-point when Conversion_OK is set
7b536495 12712
8113b0c7
EB
12713 elsif Is_Floating_Point_Type (Target_Type)
12714 or else (Is_Fixed_Point_Type (Target_Type)
12715 and then Conversion_OK (N))
12716 then
12717 Real_Range_Check;
7b536495 12718 end if;
17ea7fad
AC
12719
12720 pragma Assert (not Do_Range_Check (Expression (N)));
fbf5a39b 12721 end if;
f02b8bb8 12722
e606088a
AC
12723 -- Here at end of processing
12724
48f91b44
RD
12725 <<Done>>
12726 -- Apply predicate check if required. Note that we can't just call
12727 -- Apply_Predicate_Check here, because the type looks right after
12728 -- the conversion and it would omit the check. The Comes_From_Source
12729 -- guard is necessary to prevent infinite recursions when we generate
12730 -- internal conversions for the purpose of checking predicates.
12731
152f64c2 12732 if Predicate_Enabled (Target_Type)
48f91b44
RD
12733 and then Target_Type /= Operand_Type
12734 and then Comes_From_Source (N)
12735 then
00332244
AC
12736 declare
12737 New_Expr : constant Node_Id := Duplicate_Subexpr (N);
12738
12739 begin
152f64c2
AC
12740 -- Avoid infinite recursion on the subsequent expansion of the
12741 -- copy of the original type conversion. When needed, a range
12742 -- check has already been applied to the expression.
00332244
AC
12743
12744 Set_Comes_From_Source (New_Expr, False);
6ef13c4f 12745 Insert_Action (N,
152f64c2
AC
12746 Make_Predicate_Check (Target_Type, New_Expr),
12747 Suppress => Range_Check);
00332244 12748 end;
48f91b44 12749 end if;
70482933
RK
12750 end Expand_N_Type_Conversion;
12751
12752 -----------------------------------
12753 -- Expand_N_Unchecked_Expression --
12754 -----------------------------------
12755
e7e4d230 12756 -- Remove the unchecked expression node from the tree. Its job was simply
70482933 12757 -- to make sure that its constituent expression was handled with checks
604801a4
PT
12758 -- off, and now that is done, we can remove it from the tree, and indeed
12759 -- must, since Gigi does not expect to see these nodes.
70482933
RK
12760
12761 procedure Expand_N_Unchecked_Expression (N : Node_Id) is
12762 Exp : constant Node_Id := Expression (N);
70482933 12763 begin
e7e4d230 12764 Set_Assignment_OK (Exp, Assignment_OK (N) or else Assignment_OK (Exp));
70482933
RK
12765 Rewrite (N, Exp);
12766 end Expand_N_Unchecked_Expression;
12767
12768 ----------------------------------------
12769 -- Expand_N_Unchecked_Type_Conversion --
12770 ----------------------------------------
12771
685094bf
RD
12772 -- If this cannot be handled by Gigi and we haven't already made a
12773 -- temporary for it, do it now.
70482933
RK
12774
12775 procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id) is
12776 Target_Type : constant Entity_Id := Etype (N);
12777 Operand : constant Node_Id := Expression (N);
12778 Operand_Type : constant Entity_Id := Etype (Operand);
12779
12780 begin
7b00e31d 12781 -- Nothing at all to do if conversion is to the identical type so remove
76efd572 12782 -- the conversion completely, it is useless, except that it may carry
e7e4d230 12783 -- an Assignment_OK indication which must be propagated to the operand.
7b00e31d
AC
12784
12785 if Operand_Type = Target_Type then
0964be07 12786 Expand_N_Unchecked_Expression (N);
7b00e31d
AC
12787 return;
12788 end if;
12789
02458cc7
JM
12790 -- Generate an extra temporary for cases unsupported by the C backend
12791
12792 if Modify_Tree_For_C then
12793 declare
12794 Source : constant Node_Id := Unqual_Conv (Expression (N));
12795 Source_Typ : Entity_Id := Get_Full_View (Etype (Source));
12796
12797 begin
12798 if Is_Packed_Array (Source_Typ) then
12799 Source_Typ := Packed_Array_Impl_Type (Source_Typ);
12800 end if;
12801
12802 if Nkind (Source) = N_Function_Call
12803 and then (Is_Composite_Type (Etype (Source))
12804 or else Is_Composite_Type (Target_Type))
12805 then
12806 Force_Evaluation (Source);
12807 end if;
12808 end;
12809 end if;
12810
70482933
RK
12811 -- Nothing to do if conversion is safe
12812
12813 if Safe_Unchecked_Type_Conversion (N) then
12814 return;
12815 end if;
12816
70482933
RK
12817 if Assignment_OK (N) then
12818 null;
12819 else
12820 Force_Evaluation (N);
12821 end if;
12822 end Expand_N_Unchecked_Type_Conversion;
12823
12824 ----------------------------
12825 -- Expand_Record_Equality --
12826 ----------------------------
12827
12828 -- For non-variant records, Equality is expanded when needed into:
12829
12830 -- and then Lhs.Discr1 = Rhs.Discr1
12831 -- and then ...
12832 -- and then Lhs.Discrn = Rhs.Discrn
12833 -- and then Lhs.Cmp1 = Rhs.Cmp1
12834 -- and then ...
12835 -- and then Lhs.Cmpn = Rhs.Cmpn
12836
c7a494c9 12837 -- The expression is folded by the back end for adjacent fields. This
70482933
RK
12838 -- function is called for tagged record in only one occasion: for imple-
12839 -- menting predefined primitive equality (see Predefined_Primitives_Bodies)
12840 -- otherwise the primitive "=" is used directly.
12841
12842 function Expand_Record_Equality
12843 (Nod : Node_Id;
12844 Typ : Entity_Id;
12845 Lhs : Node_Id;
12846 Rhs : Node_Id;
2e071734 12847 Bodies : List_Id) return Node_Id
70482933
RK
12848 is
12849 Loc : constant Source_Ptr := Sloc (Nod);
12850
0ab80019
AC
12851 Result : Node_Id;
12852 C : Entity_Id;
12853
12854 First_Time : Boolean := True;
12855
6b670dcf
AC
12856 function Element_To_Compare (C : Entity_Id) return Entity_Id;
12857 -- Return the next discriminant or component to compare, starting with
12858 -- C, skipping inherited components.
0ab80019 12859
6b670dcf
AC
12860 ------------------------
12861 -- Element_To_Compare --
12862 ------------------------
70482933 12863
6b670dcf
AC
12864 function Element_To_Compare (C : Entity_Id) return Entity_Id is
12865 Comp : Entity_Id;
28270211 12866
70482933 12867 begin
6b670dcf 12868 Comp := C;
6b670dcf
AC
12869 loop
12870 -- Exit loop when the next element to be compared is found, or
12871 -- there is no more such element.
70482933 12872
6b670dcf 12873 exit when No (Comp);
8190087e 12874
4a08c95c 12875 exit when Ekind (Comp) in E_Discriminant | E_Component
6b670dcf 12876 and then not (
70482933 12877
6b670dcf 12878 -- Skip inherited components
70482933 12879
6b670dcf
AC
12880 -- Note: for a tagged type, we always generate the "=" primitive
12881 -- for the base type (not on the first subtype), so the test for
12882 -- Comp /= Original_Record_Component (Comp) is True for
12883 -- inherited components only.
24558db8 12884
6b670dcf 12885 (Is_Tagged_Type (Typ)
28270211 12886 and then Comp /= Original_Record_Component (Comp))
24558db8 12887
6b670dcf 12888 -- Skip _Tag
26bff3d9 12889
6b670dcf
AC
12890 or else Chars (Comp) = Name_uTag
12891
6b670dcf
AC
12892 -- Skip interface elements (secondary tags???)
12893
12894 or else Is_Interface (Etype (Comp)));
12895
12896 Next_Entity (Comp);
12897 end loop;
12898
12899 return Comp;
12900 end Element_To_Compare;
70482933 12901
70482933
RK
12902 -- Start of processing for Expand_Record_Equality
12903
12904 begin
70482933
RK
12905 -- Generates the following code: (assuming that Typ has one Discr and
12906 -- component C2 is also a record)
12907
63254915
AC
12908 -- Lhs.Discr1 = Rhs.Discr1
12909 -- and then Lhs.C1 = Rhs.C1
12910 -- and then Lhs.C2.C1=Rhs.C2.C1 and then ... Lhs.C2.Cn=Rhs.C2.Cn
12911 -- and then ...
12912 -- and then Lhs.Cmpn = Rhs.Cmpn
70482933 12913
e4494292 12914 Result := New_Occurrence_Of (Standard_True, Loc);
6b670dcf 12915 C := Element_To_Compare (First_Entity (Typ));
70482933 12916 while Present (C) loop
70482933
RK
12917 declare
12918 New_Lhs : Node_Id;
12919 New_Rhs : Node_Id;
8aceda64 12920 Check : Node_Id;
70482933
RK
12921
12922 begin
12923 if First_Time then
70482933
RK
12924 New_Lhs := Lhs;
12925 New_Rhs := Rhs;
70482933
RK
12926 else
12927 New_Lhs := New_Copy_Tree (Lhs);
12928 New_Rhs := New_Copy_Tree (Rhs);
12929 end if;
12930
8aceda64
AC
12931 Check :=
12932 Expand_Composite_Equality (Nod, Etype (C),
12933 Lhs =>
12934 Make_Selected_Component (Loc,
8d80ff64 12935 Prefix => New_Lhs,
e4494292 12936 Selector_Name => New_Occurrence_Of (C, Loc)),
8aceda64
AC
12937 Rhs =>
12938 Make_Selected_Component (Loc,
8d80ff64 12939 Prefix => New_Rhs,
e4494292 12940 Selector_Name => New_Occurrence_Of (C, Loc)),
8aceda64
AC
12941 Bodies => Bodies);
12942
12943 -- If some (sub)component is an unchecked_union, the whole
12944 -- operation will raise program error.
12945
12946 if Nkind (Check) = N_Raise_Program_Error then
12947 Result := Check;
12948 Set_Etype (Result, Standard_Boolean);
12949 exit;
12950 else
63254915
AC
12951 if First_Time then
12952 Result := Check;
12953
12954 -- Generate logical "and" for CodePeer to simplify the
12955 -- generated code and analysis.
12956
12957 elsif CodePeer_Mode then
12958 Result :=
12959 Make_Op_And (Loc,
12960 Left_Opnd => Result,
12961 Right_Opnd => Check);
12962
12963 else
12964 Result :=
12965 Make_And_Then (Loc,
12966 Left_Opnd => Result,
12967 Right_Opnd => Check);
12968 end if;
8aceda64 12969 end if;
70482933
RK
12970 end;
12971
63254915 12972 First_Time := False;
6b670dcf 12973 C := Element_To_Compare (Next_Entity (C));
70482933
RK
12974 end loop;
12975
12976 return Result;
12977 end Expand_Record_Equality;
12978
a3068ca6
AC
12979 ---------------------------
12980 -- Expand_Set_Membership --
12981 ---------------------------
12982
12983 procedure Expand_Set_Membership (N : Node_Id) is
12984 Lop : constant Node_Id := Left_Opnd (N);
12985 Alt : Node_Id;
12986 Res : Node_Id;
12987
12988 function Make_Cond (Alt : Node_Id) return Node_Id;
12989 -- If the alternative is a subtype mark, create a simple membership
12990 -- test. Otherwise create an equality test for it.
12991
12992 ---------------
12993 -- Make_Cond --
12994 ---------------
12995
12996 function Make_Cond (Alt : Node_Id) return Node_Id is
12997 Cond : Node_Id;
afe9c539 12998 L : constant Node_Id := New_Copy_Tree (Lop);
a3068ca6
AC
12999 R : constant Node_Id := Relocate_Node (Alt);
13000
13001 begin
13002 if (Is_Entity_Name (Alt) and then Is_Type (Entity (Alt)))
13003 or else Nkind (Alt) = N_Range
13004 then
13005 Cond :=
13006 Make_In (Sloc (Alt),
13007 Left_Opnd => L,
13008 Right_Opnd => R);
13009 else
13010 Cond :=
13011 Make_Op_Eq (Sloc (Alt),
13012 Left_Opnd => L,
13013 Right_Opnd => R);
81c35697 13014
d51bf619 13015 if Is_Record_Or_Limited_Type (Etype (Alt)) then
81c35697 13016
d51bf619
AC
13017 -- We reset the Entity in order to use the primitive equality
13018 -- of the type, as per RM 4.5.2 (28.1/4).
13019
13020 Set_Entity (Cond, Empty);
13021 end if;
a3068ca6
AC
13022 end if;
13023
13024 return Cond;
13025 end Make_Cond;
13026
13027 -- Start of processing for Expand_Set_Membership
13028
13029 begin
13030 Remove_Side_Effects (Lop);
13031
b3d77404 13032 Alt := First (Alternatives (N));
a3068ca6 13033 Res := Make_Cond (Alt);
b3d77404
EB
13034 Next (Alt);
13035
13036 -- We use left associativity as in the equivalent boolean case. This
13037 -- kind of canonicalization helps the optimizer of the code generator.
a3068ca6 13038
a3068ca6
AC
13039 while Present (Alt) loop
13040 Res :=
13041 Make_Or_Else (Sloc (Alt),
b3d77404
EB
13042 Left_Opnd => Res,
13043 Right_Opnd => Make_Cond (Alt));
13044 Next (Alt);
a3068ca6
AC
13045 end loop;
13046
13047 Rewrite (N, Res);
13048 Analyze_And_Resolve (N, Standard_Boolean);
13049 end Expand_Set_Membership;
13050
5875f8d6
AC
13051 -----------------------------------
13052 -- Expand_Short_Circuit_Operator --
13053 -----------------------------------
13054
955871d3
AC
13055 -- Deal with special expansion if actions are present for the right operand
13056 -- and deal with optimizing case of arguments being True or False. We also
13057 -- deal with the special case of non-standard boolean values.
5875f8d6
AC
13058
13059 procedure Expand_Short_Circuit_Operator (N : Node_Id) is
13060 Loc : constant Source_Ptr := Sloc (N);
13061 Typ : constant Entity_Id := Etype (N);
5875f8d6
AC
13062 Left : constant Node_Id := Left_Opnd (N);
13063 Right : constant Node_Id := Right_Opnd (N);
955871d3 13064 LocR : constant Source_Ptr := Sloc (Right);
5875f8d6
AC
13065 Actlist : List_Id;
13066
13067 Shortcut_Value : constant Boolean := Nkind (N) = N_Or_Else;
13068 Shortcut_Ent : constant Entity_Id := Boolean_Literals (Shortcut_Value);
13069 -- If Left = Shortcut_Value then Right need not be evaluated
13070
f916243b
AC
13071 function Make_Test_Expr (Opnd : Node_Id) return Node_Id;
13072 -- For Opnd a boolean expression, return a Boolean expression equivalent
13073 -- to Opnd /= Shortcut_Value.
13074
a0766a82
AC
13075 function Useful (Actions : List_Id) return Boolean;
13076 -- Return True if Actions is not empty and contains useful nodes to
13077 -- process.
13078
f916243b
AC
13079 --------------------
13080 -- Make_Test_Expr --
13081 --------------------
13082
13083 function Make_Test_Expr (Opnd : Node_Id) return Node_Id is
13084 begin
13085 if Shortcut_Value then
13086 return Make_Op_Not (Sloc (Opnd), Opnd);
13087 else
13088 return Opnd;
13089 end if;
13090 end Make_Test_Expr;
13091
a0766a82
AC
13092 ------------
13093 -- Useful --
13094 ------------
13095
13096 function Useful (Actions : List_Id) return Boolean is
13097 L : Node_Id;
13098 begin
13099 if Present (Actions) then
13100 L := First (Actions);
13101
13102 -- For now "useful" means not N_Variable_Reference_Marker.
13103 -- Consider stripping other nodes in the future.
13104
13105 while Present (L) loop
13106 if Nkind (L) /= N_Variable_Reference_Marker then
13107 return True;
13108 end if;
13109
13110 Next (L);
13111 end loop;
13112 end if;
13113
13114 return False;
13115 end Useful;
13116
f916243b
AC
13117 -- Local variables
13118
13119 Op_Var : Entity_Id;
13120 -- Entity for a temporary variable holding the value of the operator,
13121 -- used for expansion in the case where actions are present.
13122
13123 -- Start of processing for Expand_Short_Circuit_Operator
13124
5875f8d6
AC
13125 begin
13126 -- Deal with non-standard booleans
13127
13128 if Is_Boolean_Type (Typ) then
13129 Adjust_Condition (Left);
13130 Adjust_Condition (Right);
13131 Set_Etype (N, Standard_Boolean);
13132 end if;
13133
13134 -- Check for cases where left argument is known to be True or False
13135
13136 if Compile_Time_Known_Value (Left) then
25adc5fb
AC
13137
13138 -- Mark SCO for left condition as compile time known
13139
13140 if Generate_SCO and then Comes_From_Source (Left) then
13141 Set_SCO_Condition (Left, Expr_Value_E (Left) = Standard_True);
13142 end if;
13143
5875f8d6
AC
13144 -- Rewrite True AND THEN Right / False OR ELSE Right to Right.
13145 -- Any actions associated with Right will be executed unconditionally
13146 -- and can thus be inserted into the tree unconditionally.
13147
13148 if Expr_Value_E (Left) /= Shortcut_Ent then
13149 if Present (Actions (N)) then
13150 Insert_Actions (N, Actions (N));
13151 end if;
13152
13153 Rewrite (N, Right);
13154
13155 -- Rewrite False AND THEN Right / True OR ELSE Right to Left.
13156 -- In this case we can forget the actions associated with Right,
13157 -- since they will never be executed.
13158
13159 else
13160 Kill_Dead_Code (Right);
13161 Kill_Dead_Code (Actions (N));
13162 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
13163 end if;
13164
13165 Adjust_Result_Type (N, Typ);
13166 return;
13167 end if;
13168
955871d3
AC
13169 -- If Actions are present for the right operand, we have to do some
13170 -- special processing. We can't just let these actions filter back into
13171 -- code preceding the short circuit (which is what would have happened
13172 -- if we had not trapped them in the short-circuit form), since they
13173 -- must only be executed if the right operand of the short circuit is
13174 -- executed and not otherwise.
5875f8d6 13175
a0766a82 13176 if Useful (Actions (N)) then
955871d3 13177 Actlist := Actions (N);
5875f8d6 13178
f916243b
AC
13179 -- The old approach is to expand:
13180
13181 -- left AND THEN right
13182
13183 -- into
13184
13185 -- C : Boolean := False;
13186 -- IF left THEN
13187 -- Actions;
13188 -- IF right THEN
13189 -- C := True;
13190 -- END IF;
13191 -- END IF;
13192
13193 -- and finally rewrite the operator into a reference to C. Similarly
13194 -- for left OR ELSE right, with negated values. Note that this
13195 -- rewrite causes some difficulties for coverage analysis because
13196 -- of the introduction of the new variable C, which obscures the
13197 -- structure of the test.
13198
13199 -- We use this "old approach" if Minimize_Expression_With_Actions
13200 -- is True.
13201
13202 if Minimize_Expression_With_Actions then
13203 Op_Var := Make_Temporary (Loc, 'C', Related_Node => N);
13204
13205 Insert_Action (N,
13206 Make_Object_Declaration (Loc,
13207 Defining_Identifier => Op_Var,
13208 Object_Definition =>
13209 New_Occurrence_Of (Standard_Boolean, Loc),
13210 Expression =>
13211 New_Occurrence_Of (Shortcut_Ent, Loc)));
13212
13213 Append_To (Actlist,
13214 Make_Implicit_If_Statement (Right,
13215 Condition => Make_Test_Expr (Right),
13216 Then_Statements => New_List (
13217 Make_Assignment_Statement (LocR,
13218 Name => New_Occurrence_Of (Op_Var, LocR),
13219 Expression =>
13220 New_Occurrence_Of
13221 (Boolean_Literals (not Shortcut_Value), LocR)))));
13222
13223 Insert_Action (N,
13224 Make_Implicit_If_Statement (Left,
13225 Condition => Make_Test_Expr (Left),
13226 Then_Statements => Actlist));
13227
13228 Rewrite (N, New_Occurrence_Of (Op_Var, Loc));
13229 Analyze_And_Resolve (N, Standard_Boolean);
13230
13231 -- The new approach (the default) is to use an
13232 -- Expression_With_Actions node for the right operand of the
13233 -- short-circuit form. Note that this solves the traceability
0812b84e 13234 -- problems for coverage analysis.
5875f8d6 13235
f916243b
AC
13236 else
13237 Rewrite (Right,
13238 Make_Expression_With_Actions (LocR,
13239 Expression => Relocate_Node (Right),
13240 Actions => Actlist));
4b17187f 13241
f916243b
AC
13242 Set_Actions (N, No_List);
13243 Analyze_And_Resolve (Right, Standard_Boolean);
13244 end if;
955871d3 13245
5875f8d6
AC
13246 Adjust_Result_Type (N, Typ);
13247 return;
13248 end if;
13249
13250 -- No actions present, check for cases of right argument True/False
13251
13252 if Compile_Time_Known_Value (Right) then
25adc5fb
AC
13253
13254 -- Mark SCO for left condition as compile time known
13255
13256 if Generate_SCO and then Comes_From_Source (Right) then
13257 Set_SCO_Condition (Right, Expr_Value_E (Right) = Standard_True);
13258 end if;
13259
f916243b
AC
13260 -- Change (Left and then True), (Left or else False) to Left. Note
13261 -- that we know there are no actions associated with the right
5875f8d6
AC
13262 -- operand, since we just checked for this case above.
13263
13264 if Expr_Value_E (Right) /= Shortcut_Ent then
13265 Rewrite (N, Left);
13266
13267 -- Change (Left and then False), (Left or else True) to Right,
13268 -- making sure to preserve any side effects associated with the Left
13269 -- operand.
13270
13271 else
13272 Remove_Side_Effects (Left);
13273 Rewrite (N, New_Occurrence_Of (Shortcut_Ent, Loc));
13274 end if;
13275 end if;
13276
13277 Adjust_Result_Type (N, Typ);
13278 end Expand_Short_Circuit_Operator;
13279
bdbb2a40 13280 ------------------------------------
70482933
RK
13281 -- Fixup_Universal_Fixed_Operation --
13282 -------------------------------------
13283
13284 procedure Fixup_Universal_Fixed_Operation (N : Node_Id) is
13285 Conv : constant Node_Id := Parent (N);
13286
13287 begin
13288 -- We must have a type conversion immediately above us
13289
13290 pragma Assert (Nkind (Conv) = N_Type_Conversion);
13291
13292 -- Normally the type conversion gives our target type. The exception
13293 -- occurs in the case of the Round attribute, where the conversion
13294 -- will be to universal real, and our real type comes from the Round
13295 -- attribute (as well as an indication that we must round the result)
13296
32543637
EB
13297 if Etype (Conv) = Universal_Real
13298 and then Nkind (Parent (Conv)) = N_Attribute_Reference
70482933
RK
13299 and then Attribute_Name (Parent (Conv)) = Name_Round
13300 then
267c7ff6 13301 Set_Etype (N, Base_Type (Etype (Parent (Conv))));
70482933
RK
13302 Set_Rounded_Result (N);
13303
13304 -- Normal case where type comes from conversion above us
13305
13306 else
267c7ff6 13307 Set_Etype (N, Base_Type (Etype (Conv)));
70482933
RK
13308 end if;
13309 end Fixup_Universal_Fixed_Operation;
13310
2e8ee0a3
EB
13311 ------------------------
13312 -- Get_Size_For_Range --
13313 ------------------------
13314
13315 function Get_Size_For_Range (Lo, Hi : Uint) return Uint is
13316
13317 function Is_OK_For_Range (Siz : Uint) return Boolean;
13318 -- Return True if a signed integer with given size can cover Lo .. Hi
13319
13320 --------------------------
13321 -- Is_OK_For_Range --
13322 --------------------------
13323
13324 function Is_OK_For_Range (Siz : Uint) return Boolean is
13325 B : constant Uint := Uint_2 ** (Siz - 1);
13326
13327 begin
13328 -- Test B = 2 ** (size - 1) (can accommodate -B .. +(B - 1))
13329
13330 return Lo >= -B and then Hi >= -B and then Lo < B and then Hi < B;
13331 end Is_OK_For_Range;
13332
13333 begin
13334 -- This is (almost always) the size of Integer
13335
13336 if Is_OK_For_Range (Uint_32) then
13337 return Uint_32;
13338
13339 -- Check 63
13340
13341 elsif Is_OK_For_Range (Uint_63) then
13342 return Uint_63;
13343
13344 -- This is (almost always) the size of Long_Long_Integer
13345
13346 elsif Is_OK_For_Range (Uint_64) then
13347 return Uint_64;
13348
13349 -- Check 127
13350
13351 elsif Is_OK_For_Range (Uint_127) then
13352 return Uint_127;
13353
13354 else
13355 return Uint_128;
13356 end if;
13357 end Get_Size_For_Range;
13358
70482933
RK
13359 -------------------------------
13360 -- Insert_Dereference_Action --
13361 -------------------------------
13362
13363 procedure Insert_Dereference_Action (N : Node_Id) is
70482933 13364 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean;
2e071734
AC
13365 -- Return true if type of P is derived from Checked_Pool;
13366
13367 -----------------------------
13368 -- Is_Checked_Storage_Pool --
13369 -----------------------------
70482933
RK
13370
13371 function Is_Checked_Storage_Pool (P : Entity_Id) return Boolean is
13372 T : Entity_Id;
761f7dcb 13373
70482933
RK
13374 begin
13375 if No (P) then
13376 return False;
13377 end if;
13378
13379 T := Etype (P);
13380 while T /= Etype (T) loop
13381 if Is_RTE (T, RE_Checked_Pool) then
13382 return True;
13383 else
13384 T := Etype (T);
13385 end if;
13386 end loop;
13387
13388 return False;
13389 end Is_Checked_Storage_Pool;
13390
b0d71355
HK
13391 -- Local variables
13392
bb9e2aa2
AC
13393 Context : constant Node_Id := Parent (N);
13394 Ptr_Typ : constant Entity_Id := Etype (N);
13395 Desig_Typ : constant Entity_Id :=
13396 Available_View (Designated_Type (Ptr_Typ));
13397 Loc : constant Source_Ptr := Sloc (N);
13398 Pool : constant Entity_Id := Associated_Storage_Pool (Ptr_Typ);
b0d71355 13399
51dcceec
AC
13400 Addr : Entity_Id;
13401 Alig : Entity_Id;
13402 Deref : Node_Id;
13403 Size : Entity_Id;
13404 Size_Bits : Node_Id;
13405 Stmt : Node_Id;
b0d71355 13406
70482933
RK
13407 -- Start of processing for Insert_Dereference_Action
13408
13409 begin
bb9e2aa2 13410 pragma Assert (Nkind (Context) = N_Explicit_Dereference);
e6f69614 13411
b0d71355
HK
13412 -- Do not re-expand a dereference which has already been processed by
13413 -- this routine.
13414
bb9e2aa2 13415 if Has_Dereference_Action (Context) then
70482933 13416 return;
70482933 13417
b0d71355
HK
13418 -- Do not perform this type of expansion for internally-generated
13419 -- dereferences.
70482933 13420
bb9e2aa2 13421 elsif not Comes_From_Source (Original_Node (Context)) then
b0d71355 13422 return;
70482933 13423
b0d71355
HK
13424 -- A dereference action is only applicable to objects which have been
13425 -- allocated on a checked pool.
70482933 13426
b0d71355
HK
13427 elsif not Is_Checked_Storage_Pool (Pool) then
13428 return;
13429 end if;
70482933 13430
b0d71355 13431 -- Extract the address of the dereferenced object. Generate:
8777c5a6 13432
b0d71355 13433 -- Addr : System.Address := <N>'Pool_Address;
70482933 13434
b0d71355 13435 Addr := Make_Temporary (Loc, 'P');
70482933 13436
b0d71355
HK
13437 Insert_Action (N,
13438 Make_Object_Declaration (Loc,
13439 Defining_Identifier => Addr,
13440 Object_Definition =>
e4494292 13441 New_Occurrence_Of (RTE (RE_Address), Loc),
b0d71355
HK
13442 Expression =>
13443 Make_Attribute_Reference (Loc,
13444 Prefix => Duplicate_Subexpr_Move_Checks (N),
13445 Attribute_Name => Name_Pool_Address)));
13446
13447 -- Calculate the size of the dereferenced object. Generate:
8777c5a6 13448
b0d71355
HK
13449 -- Size : Storage_Count := <N>.all'Size / Storage_Unit;
13450
13451 Deref :=
13452 Make_Explicit_Dereference (Loc,
13453 Prefix => Duplicate_Subexpr_Move_Checks (N));
13454 Set_Has_Dereference_Action (Deref);
70482933 13455
51dcceec
AC
13456 Size_Bits :=
13457 Make_Attribute_Reference (Loc,
13458 Prefix => Deref,
13459 Attribute_Name => Name_Size);
13460
13461 -- Special case of an unconstrained array: need to add descriptor size
13462
bb9e2aa2
AC
13463 if Is_Array_Type (Desig_Typ)
13464 and then not Is_Constrained (First_Subtype (Desig_Typ))
51dcceec
AC
13465 then
13466 Size_Bits :=
13467 Make_Op_Add (Loc,
13468 Left_Opnd =>
13469 Make_Attribute_Reference (Loc,
13470 Prefix =>
bb9e2aa2 13471 New_Occurrence_Of (First_Subtype (Desig_Typ), Loc),
51dcceec
AC
13472 Attribute_Name => Name_Descriptor_Size),
13473 Right_Opnd => Size_Bits);
13474 end if;
b0d71355 13475
51dcceec 13476 Size := Make_Temporary (Loc, 'S');
b0d71355
HK
13477 Insert_Action (N,
13478 Make_Object_Declaration (Loc,
13479 Defining_Identifier => Size,
13480 Object_Definition =>
e4494292 13481 New_Occurrence_Of (RTE (RE_Storage_Count), Loc),
b0d71355
HK
13482 Expression =>
13483 Make_Op_Divide (Loc,
51dcceec
AC
13484 Left_Opnd => Size_Bits,
13485 Right_Opnd => Make_Integer_Literal (Loc, System_Storage_Unit))));
70482933 13486
b0d71355
HK
13487 -- Calculate the alignment of the dereferenced object. Generate:
13488 -- Alig : constant Storage_Count := <N>.all'Alignment;
70482933 13489
b0d71355
HK
13490 Deref :=
13491 Make_Explicit_Dereference (Loc,
13492 Prefix => Duplicate_Subexpr_Move_Checks (N));
13493 Set_Has_Dereference_Action (Deref);
13494
13495 Alig := Make_Temporary (Loc, 'A');
b0d71355
HK
13496 Insert_Action (N,
13497 Make_Object_Declaration (Loc,
13498 Defining_Identifier => Alig,
13499 Object_Definition =>
e4494292 13500 New_Occurrence_Of (RTE (RE_Storage_Count), Loc),
b0d71355
HK
13501 Expression =>
13502 Make_Attribute_Reference (Loc,
13503 Prefix => Deref,
13504 Attribute_Name => Name_Alignment)));
13505
13506 -- A dereference of a controlled object requires special processing. The
13507 -- finalization machinery requests additional space from the underlying
13508 -- pool to allocate and hide two pointers. As a result, a checked pool
13509 -- may mark the wrong memory as valid. Since checked pools do not have
13510 -- knowledge of hidden pointers, we have to bring the two pointers back
13511 -- in view in order to restore the original state of the object.
13512
bb9e2aa2
AC
13513 -- The address manipulation is not performed for access types that are
13514 -- subject to pragma No_Heap_Finalization because the two pointers do
13515 -- not exist in the first place.
13516
13517 if No_Heap_Finalization (Ptr_Typ) then
13518 null;
13519
13520 elsif Needs_Finalization (Desig_Typ) then
b0d71355
HK
13521
13522 -- Adjust the address and size of the dereferenced object. Generate:
13523 -- Adjust_Controlled_Dereference (Addr, Size, Alig);
13524
13525 Stmt :=
13526 Make_Procedure_Call_Statement (Loc,
13527 Name =>
e4494292 13528 New_Occurrence_Of (RTE (RE_Adjust_Controlled_Dereference), Loc),
b0d71355 13529 Parameter_Associations => New_List (
e4494292
RD
13530 New_Occurrence_Of (Addr, Loc),
13531 New_Occurrence_Of (Size, Loc),
13532 New_Occurrence_Of (Alig, Loc)));
b0d71355
HK
13533
13534 -- Class-wide types complicate things because we cannot determine
13535 -- statically whether the actual object is truly controlled. We must
13536 -- generate a runtime check to detect this property. Generate:
13537 --
13538 -- if Needs_Finalization (<N>.all'Tag) then
13539 -- <Stmt>;
13540 -- end if;
13541
bb9e2aa2 13542 if Is_Class_Wide_Type (Desig_Typ) then
b0d71355
HK
13543 Deref :=
13544 Make_Explicit_Dereference (Loc,
13545 Prefix => Duplicate_Subexpr_Move_Checks (N));
13546 Set_Has_Dereference_Action (Deref);
13547
13548 Stmt :=
8b1011c0 13549 Make_Implicit_If_Statement (N,
b0d71355
HK
13550 Condition =>
13551 Make_Function_Call (Loc,
13552 Name =>
e4494292 13553 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
b0d71355
HK
13554 Parameter_Associations => New_List (
13555 Make_Attribute_Reference (Loc,
13556 Prefix => Deref,
13557 Attribute_Name => Name_Tag))),
13558 Then_Statements => New_List (Stmt));
13559 end if;
13560
13561 Insert_Action (N, Stmt);
13562 end if;
13563
13564 -- Generate:
13565 -- Dereference (Pool, Addr, Size, Alig);
13566
13567 Insert_Action (N,
13568 Make_Procedure_Call_Statement (Loc,
13569 Name =>
e4494292 13570 New_Occurrence_Of
b0d71355
HK
13571 (Find_Prim_Op (Etype (Pool), Name_Dereference), Loc),
13572 Parameter_Associations => New_List (
e4494292
RD
13573 New_Occurrence_Of (Pool, Loc),
13574 New_Occurrence_Of (Addr, Loc),
13575 New_Occurrence_Of (Size, Loc),
13576 New_Occurrence_Of (Alig, Loc))));
b0d71355
HK
13577
13578 -- Mark the explicit dereference as processed to avoid potential
13579 -- infinite expansion.
13580
bb9e2aa2 13581 Set_Has_Dereference_Action (Context);
70482933 13582
fbf5a39b
AC
13583 exception
13584 when RE_Not_Available =>
13585 return;
70482933
RK
13586 end Insert_Dereference_Action;
13587
fdfcc663
AC
13588 --------------------------------
13589 -- Integer_Promotion_Possible --
13590 --------------------------------
13591
13592 function Integer_Promotion_Possible (N : Node_Id) return Boolean is
13593 Operand : constant Node_Id := Expression (N);
13594 Operand_Type : constant Entity_Id := Etype (Operand);
13595 Root_Operand_Type : constant Entity_Id := Root_Type (Operand_Type);
13596
13597 begin
13598 pragma Assert (Nkind (N) = N_Type_Conversion);
13599
13600 return
13601
13602 -- We only do the transformation for source constructs. We assume
13603 -- that the expander knows what it is doing when it generates code.
13604
13605 Comes_From_Source (N)
13606
13607 -- If the operand type is Short_Integer or Short_Short_Integer,
13608 -- then we will promote to Integer, which is available on all
13609 -- targets, and is sufficient to ensure no intermediate overflow.
13610 -- Furthermore it is likely to be as efficient or more efficient
13611 -- than using the smaller type for the computation so we do this
13612 -- unconditionally.
13613
13614 and then
13615 (Root_Operand_Type = Base_Type (Standard_Short_Integer)
761f7dcb 13616 or else
fdfcc663
AC
13617 Root_Operand_Type = Base_Type (Standard_Short_Short_Integer))
13618
13619 -- Test for interesting operation, which includes addition,
5f3f175d
AC
13620 -- division, exponentiation, multiplication, subtraction, absolute
13621 -- value and unary negation. Unary "+" is omitted since it is a
13622 -- no-op and thus can't overflow.
fdfcc663 13623
4a08c95c
AC
13624 and then Nkind (Operand) in
13625 N_Op_Abs | N_Op_Add | N_Op_Divide | N_Op_Expon |
13626 N_Op_Minus | N_Op_Multiply | N_Op_Subtract;
fdfcc663
AC
13627 end Integer_Promotion_Possible;
13628
70482933
RK
13629 ------------------------------
13630 -- Make_Array_Comparison_Op --
13631 ------------------------------
13632
13633 -- This is a hand-coded expansion of the following generic function:
13634
13635 -- generic
13636 -- type elem is (<>);
13637 -- type index is (<>);
13638 -- type a is array (index range <>) of elem;
20b5d666 13639
70482933
RK
13640 -- function Gnnn (X : a; Y: a) return boolean is
13641 -- J : index := Y'first;
20b5d666 13642
70482933
RK
13643 -- begin
13644 -- if X'length = 0 then
13645 -- return false;
20b5d666 13646
70482933
RK
13647 -- elsif Y'length = 0 then
13648 -- return true;
20b5d666 13649
70482933
RK
13650 -- else
13651 -- for I in X'range loop
13652 -- if X (I) = Y (J) then
13653 -- if J = Y'last then
13654 -- exit;
13655 -- else
13656 -- J := index'succ (J);
13657 -- end if;
20b5d666 13658
70482933
RK
13659 -- else
13660 -- return X (I) > Y (J);
13661 -- end if;
13662 -- end loop;
20b5d666 13663
70482933
RK
13664 -- return X'length > Y'length;
13665 -- end if;
13666 -- end Gnnn;
13667
13668 -- Note that since we are essentially doing this expansion by hand, we
13669 -- do not need to generate an actual or formal generic part, just the
13670 -- instantiated function itself.
13671
13672 function Make_Array_Comparison_Op
2e071734
AC
13673 (Typ : Entity_Id;
13674 Nod : Node_Id) return Node_Id
70482933
RK
13675 is
13676 Loc : constant Source_Ptr := Sloc (Nod);
13677
13678 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uX);
13679 Y : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uY);
13680 I : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uI);
13681 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
13682
13683 Index : constant Entity_Id := Base_Type (Etype (First_Index (Typ)));
13684
13685 Loop_Statement : Node_Id;
13686 Loop_Body : Node_Id;
13687 If_Stat : Node_Id;
13688 Inner_If : Node_Id;
13689 Final_Expr : Node_Id;
13690 Func_Body : Node_Id;
13691 Func_Name : Entity_Id;
13692 Formals : List_Id;
13693 Length1 : Node_Id;
13694 Length2 : Node_Id;
13695
13696 begin
13697 -- if J = Y'last then
13698 -- exit;
13699 -- else
13700 -- J := index'succ (J);
13701 -- end if;
13702
13703 Inner_If :=
13704 Make_Implicit_If_Statement (Nod,
13705 Condition =>
13706 Make_Op_Eq (Loc,
e4494292 13707 Left_Opnd => New_Occurrence_Of (J, Loc),
70482933
RK
13708 Right_Opnd =>
13709 Make_Attribute_Reference (Loc,
e4494292 13710 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
13711 Attribute_Name => Name_Last)),
13712
13713 Then_Statements => New_List (
13714 Make_Exit_Statement (Loc)),
13715
13716 Else_Statements =>
13717 New_List (
13718 Make_Assignment_Statement (Loc,
e4494292 13719 Name => New_Occurrence_Of (J, Loc),
70482933
RK
13720 Expression =>
13721 Make_Attribute_Reference (Loc,
e4494292 13722 Prefix => New_Occurrence_Of (Index, Loc),
70482933 13723 Attribute_Name => Name_Succ,
e4494292 13724 Expressions => New_List (New_Occurrence_Of (J, Loc))))));
70482933
RK
13725
13726 -- if X (I) = Y (J) then
13727 -- if ... end if;
13728 -- else
13729 -- return X (I) > Y (J);
13730 -- end if;
13731
13732 Loop_Body :=
13733 Make_Implicit_If_Statement (Nod,
13734 Condition =>
13735 Make_Op_Eq (Loc,
13736 Left_Opnd =>
13737 Make_Indexed_Component (Loc,
e4494292
RD
13738 Prefix => New_Occurrence_Of (X, Loc),
13739 Expressions => New_List (New_Occurrence_Of (I, Loc))),
70482933
RK
13740
13741 Right_Opnd =>
13742 Make_Indexed_Component (Loc,
e4494292
RD
13743 Prefix => New_Occurrence_Of (Y, Loc),
13744 Expressions => New_List (New_Occurrence_Of (J, Loc)))),
70482933
RK
13745
13746 Then_Statements => New_List (Inner_If),
13747
13748 Else_Statements => New_List (
d766cee3 13749 Make_Simple_Return_Statement (Loc,
70482933
RK
13750 Expression =>
13751 Make_Op_Gt (Loc,
13752 Left_Opnd =>
13753 Make_Indexed_Component (Loc,
e4494292
RD
13754 Prefix => New_Occurrence_Of (X, Loc),
13755 Expressions => New_List (New_Occurrence_Of (I, Loc))),
70482933
RK
13756
13757 Right_Opnd =>
13758 Make_Indexed_Component (Loc,
e4494292 13759 Prefix => New_Occurrence_Of (Y, Loc),
70482933 13760 Expressions => New_List (
e4494292 13761 New_Occurrence_Of (J, Loc)))))));
70482933
RK
13762
13763 -- for I in X'range loop
13764 -- if ... end if;
13765 -- end loop;
13766
13767 Loop_Statement :=
13768 Make_Implicit_Loop_Statement (Nod,
13769 Identifier => Empty,
13770
13771 Iteration_Scheme =>
13772 Make_Iteration_Scheme (Loc,
13773 Loop_Parameter_Specification =>
13774 Make_Loop_Parameter_Specification (Loc,
13775 Defining_Identifier => I,
13776 Discrete_Subtype_Definition =>
13777 Make_Attribute_Reference (Loc,
e4494292 13778 Prefix => New_Occurrence_Of (X, Loc),
70482933
RK
13779 Attribute_Name => Name_Range))),
13780
13781 Statements => New_List (Loop_Body));
13782
13783 -- if X'length = 0 then
13784 -- return false;
13785 -- elsif Y'length = 0 then
13786 -- return true;
13787 -- else
13788 -- for ... loop ... end loop;
13789 -- return X'length > Y'length;
13790 -- end if;
13791
13792 Length1 :=
13793 Make_Attribute_Reference (Loc,
e4494292 13794 Prefix => New_Occurrence_Of (X, Loc),
70482933
RK
13795 Attribute_Name => Name_Length);
13796
13797 Length2 :=
13798 Make_Attribute_Reference (Loc,
e4494292 13799 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
13800 Attribute_Name => Name_Length);
13801
13802 Final_Expr :=
13803 Make_Op_Gt (Loc,
13804 Left_Opnd => Length1,
13805 Right_Opnd => Length2);
13806
13807 If_Stat :=
13808 Make_Implicit_If_Statement (Nod,
13809 Condition =>
13810 Make_Op_Eq (Loc,
13811 Left_Opnd =>
13812 Make_Attribute_Reference (Loc,
e4494292 13813 Prefix => New_Occurrence_Of (X, Loc),
70482933
RK
13814 Attribute_Name => Name_Length),
13815 Right_Opnd =>
13816 Make_Integer_Literal (Loc, 0)),
13817
13818 Then_Statements =>
13819 New_List (
d766cee3 13820 Make_Simple_Return_Statement (Loc,
e4494292 13821 Expression => New_Occurrence_Of (Standard_False, Loc))),
70482933
RK
13822
13823 Elsif_Parts => New_List (
13824 Make_Elsif_Part (Loc,
13825 Condition =>
13826 Make_Op_Eq (Loc,
13827 Left_Opnd =>
13828 Make_Attribute_Reference (Loc,
e4494292 13829 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
13830 Attribute_Name => Name_Length),
13831 Right_Opnd =>
13832 Make_Integer_Literal (Loc, 0)),
13833
13834 Then_Statements =>
13835 New_List (
d766cee3 13836 Make_Simple_Return_Statement (Loc,
e4494292 13837 Expression => New_Occurrence_Of (Standard_True, Loc))))),
70482933
RK
13838
13839 Else_Statements => New_List (
13840 Loop_Statement,
d766cee3 13841 Make_Simple_Return_Statement (Loc,
70482933
RK
13842 Expression => Final_Expr)));
13843
13844 -- (X : a; Y: a)
13845
13846 Formals := New_List (
13847 Make_Parameter_Specification (Loc,
13848 Defining_Identifier => X,
e4494292 13849 Parameter_Type => New_Occurrence_Of (Typ, Loc)),
70482933
RK
13850
13851 Make_Parameter_Specification (Loc,
13852 Defining_Identifier => Y,
e4494292 13853 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
70482933
RK
13854
13855 -- function Gnnn (...) return boolean is
13856 -- J : index := Y'first;
13857 -- begin
13858 -- if ... end if;
13859 -- end Gnnn;
13860
191fcb3a 13861 Func_Name := Make_Temporary (Loc, 'G');
70482933
RK
13862
13863 Func_Body :=
13864 Make_Subprogram_Body (Loc,
13865 Specification =>
13866 Make_Function_Specification (Loc,
13867 Defining_Unit_Name => Func_Name,
13868 Parameter_Specifications => Formals,
e4494292 13869 Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),
70482933
RK
13870
13871 Declarations => New_List (
13872 Make_Object_Declaration (Loc,
13873 Defining_Identifier => J,
e4494292 13874 Object_Definition => New_Occurrence_Of (Index, Loc),
70482933
RK
13875 Expression =>
13876 Make_Attribute_Reference (Loc,
e4494292 13877 Prefix => New_Occurrence_Of (Y, Loc),
70482933
RK
13878 Attribute_Name => Name_First))),
13879
13880 Handled_Statement_Sequence =>
13881 Make_Handled_Sequence_Of_Statements (Loc,
13882 Statements => New_List (If_Stat)));
13883
13884 return Func_Body;
70482933
RK
13885 end Make_Array_Comparison_Op;
13886
13887 ---------------------------
13888 -- Make_Boolean_Array_Op --
13889 ---------------------------
13890
685094bf
RD
13891 -- For logical operations on boolean arrays, expand in line the following,
13892 -- replacing 'and' with 'or' or 'xor' where needed:
70482933
RK
13893
13894 -- function Annn (A : typ; B: typ) return typ is
13895 -- C : typ;
13896 -- begin
13897 -- for J in A'range loop
13898 -- C (J) := A (J) op B (J);
13899 -- end loop;
13900 -- return C;
13901 -- end Annn;
13902
b50706ef
AC
13903 -- or in the case of Transform_Function_Array:
13904
13905 -- procedure Annn (A : typ; B: typ; RESULT: out typ) is
13906 -- begin
13907 -- for J in A'range loop
13908 -- RESULT (J) := A (J) op B (J);
13909 -- end loop;
13910 -- end Annn;
13911
70482933
RK
13912 -- Here typ is the boolean array type
13913
13914 function Make_Boolean_Array_Op
2e071734
AC
13915 (Typ : Entity_Id;
13916 N : Node_Id) return Node_Id
70482933
RK
13917 is
13918 Loc : constant Source_Ptr := Sloc (N);
13919
13920 A : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uA);
13921 B : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uB);
70482933
RK
13922 J : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uJ);
13923
b50706ef
AC
13924 C : Entity_Id;
13925
70482933
RK
13926 A_J : Node_Id;
13927 B_J : Node_Id;
13928 C_J : Node_Id;
13929 Op : Node_Id;
13930
13931 Formals : List_Id;
13932 Func_Name : Entity_Id;
13933 Func_Body : Node_Id;
13934 Loop_Statement : Node_Id;
13935
13936 begin
b50706ef
AC
13937 if Transform_Function_Array then
13938 C := Make_Defining_Identifier (Loc, Name_UP_RESULT);
13939 else
13940 C := Make_Defining_Identifier (Loc, Name_uC);
13941 end if;
13942
70482933
RK
13943 A_J :=
13944 Make_Indexed_Component (Loc,
e4494292
RD
13945 Prefix => New_Occurrence_Of (A, Loc),
13946 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
13947
13948 B_J :=
13949 Make_Indexed_Component (Loc,
e4494292
RD
13950 Prefix => New_Occurrence_Of (B, Loc),
13951 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
13952
13953 C_J :=
13954 Make_Indexed_Component (Loc,
e4494292
RD
13955 Prefix => New_Occurrence_Of (C, Loc),
13956 Expressions => New_List (New_Occurrence_Of (J, Loc)));
70482933
RK
13957
13958 if Nkind (N) = N_Op_And then
13959 Op :=
13960 Make_Op_And (Loc,
13961 Left_Opnd => A_J,
13962 Right_Opnd => B_J);
13963
13964 elsif Nkind (N) = N_Op_Or then
13965 Op :=
13966 Make_Op_Or (Loc,
13967 Left_Opnd => A_J,
13968 Right_Opnd => B_J);
13969
13970 else
13971 Op :=
13972 Make_Op_Xor (Loc,
13973 Left_Opnd => A_J,
13974 Right_Opnd => B_J);
13975 end if;
13976
13977 Loop_Statement :=
13978 Make_Implicit_Loop_Statement (N,
13979 Identifier => Empty,
13980
13981 Iteration_Scheme =>
13982 Make_Iteration_Scheme (Loc,
13983 Loop_Parameter_Specification =>
13984 Make_Loop_Parameter_Specification (Loc,
13985 Defining_Identifier => J,
13986 Discrete_Subtype_Definition =>
13987 Make_Attribute_Reference (Loc,
e4494292 13988 Prefix => New_Occurrence_Of (A, Loc),
70482933
RK
13989 Attribute_Name => Name_Range))),
13990
13991 Statements => New_List (
13992 Make_Assignment_Statement (Loc,
13993 Name => C_J,
13994 Expression => Op)));
13995
13996 Formals := New_List (
13997 Make_Parameter_Specification (Loc,
13998 Defining_Identifier => A,
e4494292 13999 Parameter_Type => New_Occurrence_Of (Typ, Loc)),
70482933
RK
14000
14001 Make_Parameter_Specification (Loc,
14002 Defining_Identifier => B,
e4494292 14003 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
70482933 14004
b50706ef
AC
14005 if Transform_Function_Array then
14006 Append_To (Formals,
14007 Make_Parameter_Specification (Loc,
14008 Defining_Identifier => C,
14009 Out_Present => True,
14010 Parameter_Type => New_Occurrence_Of (Typ, Loc)));
14011 end if;
14012
191fcb3a 14013 Func_Name := Make_Temporary (Loc, 'A');
70482933
RK
14014 Set_Is_Inlined (Func_Name);
14015
b50706ef
AC
14016 if Transform_Function_Array then
14017 Func_Body :=
14018 Make_Subprogram_Body (Loc,
14019 Specification =>
14020 Make_Procedure_Specification (Loc,
14021 Defining_Unit_Name => Func_Name,
14022 Parameter_Specifications => Formals),
70482933 14023
b50706ef 14024 Declarations => New_List,
70482933 14025
b50706ef
AC
14026 Handled_Statement_Sequence =>
14027 Make_Handled_Sequence_Of_Statements (Loc,
14028 Statements => New_List (Loop_Statement)));
14029
14030 else
14031 Func_Body :=
14032 Make_Subprogram_Body (Loc,
14033 Specification =>
14034 Make_Function_Specification (Loc,
14035 Defining_Unit_Name => Func_Name,
14036 Parameter_Specifications => Formals,
14037 Result_Definition => New_Occurrence_Of (Typ, Loc)),
14038
14039 Declarations => New_List (
14040 Make_Object_Declaration (Loc,
14041 Defining_Identifier => C,
14042 Object_Definition => New_Occurrence_Of (Typ, Loc))),
14043
14044 Handled_Statement_Sequence =>
14045 Make_Handled_Sequence_Of_Statements (Loc,
14046 Statements => New_List (
14047 Loop_Statement,
14048 Make_Simple_Return_Statement (Loc,
14049 Expression => New_Occurrence_Of (C, Loc)))));
14050 end if;
70482933
RK
14051
14052 return Func_Body;
14053 end Make_Boolean_Array_Op;
14054
b6b5cca8
AC
14055 -----------------------------------------
14056 -- Minimized_Eliminated_Overflow_Check --
14057 -----------------------------------------
14058
14059 function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean is
14060 begin
b55ef4b8
EB
14061 -- The MINIMIZED mode operates in Long_Long_Integer so we cannot use it
14062 -- if the type of the expression is already larger.
14063
b6b5cca8
AC
14064 return
14065 Is_Signed_Integer_Type (Etype (N))
b55ef4b8
EB
14066 and then Overflow_Check_Mode in Minimized_Or_Eliminated
14067 and then not (Overflow_Check_Mode = Minimized
14068 and then
14069 Esize (Etype (N)) > Standard_Long_Long_Integer_Size);
b6b5cca8
AC
14070 end Minimized_Eliminated_Overflow_Check;
14071
6c8e4f7e
EB
14072 ----------------------------
14073 -- Narrow_Large_Operation --
14074 ----------------------------
14075
14076 procedure Narrow_Large_Operation (N : Node_Id) is
14077 Kind : constant Node_Kind := Nkind (N);
14078 In_Rng : constant Boolean := Kind = N_In;
14079 Binary : constant Boolean := Kind in N_Binary_Op or else In_Rng;
14080 Compar : constant Boolean := Kind in N_Op_Compare or else In_Rng;
14081 R : constant Node_Id := Right_Opnd (N);
14082 Typ : constant Entity_Id := Etype (R);
cbe3b8d4 14083 Tsiz : constant Uint := RM_Size (Typ);
6c8e4f7e 14084
6c8e4f7e
EB
14085 -- Local variables
14086
14087 L : Node_Id;
14088 Llo, Lhi : Uint;
14089 Rlo, Rhi : Uint;
cbe3b8d4 14090 Lsiz, Rsiz : Uint;
6c8e4f7e 14091 Nlo, Nhi : Uint;
cbe3b8d4 14092 Nsiz : Uint;
6c8e4f7e
EB
14093 Ntyp : Entity_Id;
14094 Nop : Node_Id;
14095 OK : Boolean;
14096
14097 -- Start of processing for Narrow_Large_Operation
14098
14099 begin
14100 -- First, determine the range of the left operand, if any
14101
14102 if Binary then
14103 L := Left_Opnd (N);
14104 Determine_Range (L, OK, Llo, Lhi, Assume_Valid => True);
14105 if not OK then
14106 return;
14107 end if;
14108
14109 else
14110 L := Empty;
14111 Llo := Uint_0;
14112 Lhi := Uint_0;
14113 end if;
14114
14115 -- Second, determine the range of the right operand, which can itself
14116 -- be a range, in which case we take the lower bound of the low bound
14117 -- and the upper bound of the high bound.
14118
14119 if In_Rng then
14120 declare
14121 Zlo, Zhi : Uint;
14122
14123 begin
14124 Determine_Range
14125 (Low_Bound (R), OK, Rlo, Zhi, Assume_Valid => True);
14126 if not OK then
14127 return;
14128 end if;
14129
14130 Determine_Range
14131 (High_Bound (R), OK, Zlo, Rhi, Assume_Valid => True);
14132 if not OK then
14133 return;
14134 end if;
14135 end;
14136
14137 else
14138 Determine_Range (R, OK, Rlo, Rhi, Assume_Valid => True);
14139 if not OK then
14140 return;
14141 end if;
14142 end if;
14143
14144 -- Then compute a size suitable for each range
14145
14146 if Binary then
14147 Lsiz := Get_Size_For_Range (Llo, Lhi);
14148 else
cbe3b8d4 14149 Lsiz := Uint_0;
6c8e4f7e
EB
14150 end if;
14151
14152 Rsiz := Get_Size_For_Range (Rlo, Rhi);
14153
14154 -- Now compute the size of the narrower type
14155
14156 if Compar then
aaa3a675 14157 -- The type must be able to accommodate the operands
6c8e4f7e 14158
cbe3b8d4 14159 Nsiz := UI_Max (Lsiz, Rsiz);
6c8e4f7e
EB
14160
14161 else
aaa3a675 14162 -- The type must be able to accommodate the operand(s) and result.
6c8e4f7e
EB
14163
14164 -- Note that Determine_Range typically does not report the bounds of
14165 -- the value as being larger than those of the base type, which means
14166 -- that it does not report overflow (see also Enable_Overflow_Check).
14167
14168 Determine_Range (N, OK, Nlo, Nhi, Assume_Valid => True);
14169 if not OK then
14170 return;
14171 end if;
14172
14173 -- Therefore, if Nsiz is not lower than the size of the original type
14174 -- here, we cannot be sure that the operation does not overflow.
14175
14176 Nsiz := Get_Size_For_Range (Nlo, Nhi);
cbe3b8d4
EB
14177 Nsiz := UI_Max (Nsiz, Lsiz);
14178 Nsiz := UI_Max (Nsiz, Rsiz);
6c8e4f7e
EB
14179 end if;
14180
14181 -- If the size is not lower than the size of the original type, then
14182 -- there is no point in changing the type, except in the case where
14183 -- we can remove a conversion to the original type from an operand.
14184
cbe3b8d4 14185 if Nsiz >= Tsiz
6c8e4f7e
EB
14186 and then not (Binary
14187 and then Nkind (L) = N_Type_Conversion
14188 and then Entity (Subtype_Mark (L)) = Typ)
14189 and then not (Nkind (R) = N_Type_Conversion
14190 and then Entity (Subtype_Mark (R)) = Typ)
14191 then
14192 return;
14193 end if;
14194
19036072
EB
14195 -- Now pick the narrower type according to the size. We use the base
14196 -- type instead of the first subtype because operations are done in
14197 -- the base type, so this avoids the need for useless conversions.
6c8e4f7e 14198
a5476382
EB
14199 if Nsiz <= System_Max_Integer_Size then
14200 Ntyp := Etype (Integer_Type_For (Nsiz, Uns => False));
6c8e4f7e
EB
14201 else
14202 return;
14203 end if;
14204
aaa3a675 14205 -- Finally, rewrite the operation in the narrower type
6c8e4f7e
EB
14206
14207 Nop := New_Op_Node (Kind, Sloc (N));
14208
14209 if Binary then
14210 Set_Left_Opnd (Nop, Convert_To (Ntyp, L));
14211 end if;
14212
14213 if In_Rng then
14214 Set_Right_Opnd (Nop,
14215 Make_Range (Sloc (N),
14216 Convert_To (Ntyp, Low_Bound (R)),
14217 Convert_To (Ntyp, High_Bound (R))));
14218 else
14219 Set_Right_Opnd (Nop, Convert_To (Ntyp, R));
14220 end if;
14221
14222 Rewrite (N, Nop);
14223
14224 if Compar then
14225 -- Analyze it with the comparison type and checks suppressed since
14226 -- the conversions of the operands cannot overflow.
14227
14228 Analyze_And_Resolve
14229 (N, Etype (Original_Node (N)), Suppress => Overflow_Check);
14230
14231 else
14232 -- Analyze it with the narrower type and checks suppressed, but only
14233 -- when we are sure that the operation does not overflow, see above.
14234
cbe3b8d4 14235 if Nsiz < Tsiz then
6c8e4f7e
EB
14236 Analyze_And_Resolve (N, Ntyp, Suppress => Overflow_Check);
14237 else
14238 Analyze_And_Resolve (N, Ntyp);
14239 end if;
14240
14241 -- Put back a conversion to the original type
14242
14243 Convert_To_And_Rewrite (Typ, N);
14244 end if;
14245 end Narrow_Large_Operation;
14246
0580d807
AC
14247 --------------------------------
14248 -- Optimize_Length_Comparison --
14249 --------------------------------
14250
14251 procedure Optimize_Length_Comparison (N : Node_Id) is
14252 Loc : constant Source_Ptr := Sloc (N);
14253 Typ : constant Entity_Id := Etype (N);
14254 Result : Node_Id;
14255
14256 Left : Node_Id;
14257 Right : Node_Id;
14258 -- First and Last attribute reference nodes, which end up as left and
14259 -- right operands of the optimized result.
14260
14261 Is_Zero : Boolean;
14262 -- True for comparison operand of zero
14263
22b5aff2
EB
14264 Maybe_Superflat : Boolean;
14265 -- True if we may be in the dynamic superflat case, i.e. Is_Zero is set
14266 -- to false but the comparison operand can be zero at run time. In this
14267 -- case, we normally cannot do anything because the canonical formula of
14268 -- the length is not valid, but there is one exception: when the operand
14269 -- is itself the length of an array with the same bounds as the array on
14270 -- the LHS, we can entirely optimize away the comparison.
14271
0580d807
AC
14272 Comp : Node_Id;
14273 -- Comparison operand, set only if Is_Zero is false
14274
ac8806c4
EB
14275 Ent : array (Pos range 1 .. 2) of Entity_Id := (Empty, Empty);
14276 -- Entities whose length is being compared
0580d807 14277
ac8806c4
EB
14278 Index : array (Pos range 1 .. 2) of Node_Id := (Empty, Empty);
14279 -- Integer_Literal nodes for length attribute expressions, or Empty
0580d807
AC
14280 -- if there is no such expression present.
14281
0580d807
AC
14282 Op : Node_Kind := Nkind (N);
14283 -- Kind of comparison operator, gets flipped if operands backwards
14284
ac8806c4
EB
14285 function Convert_To_Long_Long_Integer (N : Node_Id) return Node_Id;
14286 -- Given a discrete expression, returns a Long_Long_Integer typed
14287 -- expression representing the underlying value of the expression.
14288 -- This is done with an unchecked conversion to Long_Long_Integer.
14289 -- We use unchecked conversion to handle the enumeration type case.
14290
ac8806c4 14291 function Is_Entity_Length (N : Node_Id; Num : Pos) return Boolean;
0580d807
AC
14292 -- Tests if N is a length attribute applied to a simple entity. If so,
14293 -- returns True, and sets Ent to the entity, and Index to the integer
14294 -- literal provided as an attribute expression, or to Empty if none.
ac8806c4 14295 -- Num is the index designating the relevant slot in Ent and Index.
0580d807
AC
14296 -- Also returns True if the expression is a generated type conversion
14297 -- whose expression is of the desired form. This latter case arises
14298 -- when Apply_Universal_Integer_Attribute_Check installs a conversion
14299 -- to check for being in range, which is not needed in this context.
14300 -- Returns False if neither condition holds.
14301
22b5aff2
EB
14302 function Is_Optimizable (N : Node_Id) return Boolean;
14303 -- Tests N to see if it is an optimizable comparison value (defined as
14304 -- constant zero or one, or something else where the value is known to
14305 -- be nonnegative and in the 32-bit range and where the corresponding
14306 -- Length value is also known to be 32 bits). If result is true, sets
14307 -- Is_Zero, Maybe_Superflat and Comp accordingly.
14308
14309 procedure Rewrite_For_Equal_Lengths;
14310 -- Rewrite the comparison of two equal lengths into either True or False
14311
ac8806c4
EB
14312 ----------------------------------
14313 -- Convert_To_Long_Long_Integer --
14314 ----------------------------------
14315
14316 function Convert_To_Long_Long_Integer (N : Node_Id) return Node_Id is
14317 begin
14318 return Unchecked_Convert_To (Standard_Long_Long_Integer, N);
14319 end Convert_To_Long_Long_Integer;
0580d807
AC
14320
14321 ----------------------
14322 -- Is_Entity_Length --
14323 ----------------------
14324
ac8806c4 14325 function Is_Entity_Length (N : Node_Id; Num : Pos) return Boolean is
0580d807
AC
14326 begin
14327 if Nkind (N) = N_Attribute_Reference
14328 and then Attribute_Name (N) = Name_Length
14329 and then Is_Entity_Name (Prefix (N))
14330 then
ac8806c4 14331 Ent (Num) := Entity (Prefix (N));
0580d807
AC
14332
14333 if Present (Expressions (N)) then
ac8806c4 14334 Index (Num) := First (Expressions (N));
0580d807 14335 else
ac8806c4 14336 Index (Num) := Empty;
0580d807
AC
14337 end if;
14338
14339 return True;
14340
14341 elsif Nkind (N) = N_Type_Conversion
14342 and then not Comes_From_Source (N)
14343 then
ac8806c4 14344 return Is_Entity_Length (Expression (N), Num);
0580d807
AC
14345
14346 else
14347 return False;
14348 end if;
14349 end Is_Entity_Length;
14350
14351 --------------------
14352 -- Is_Optimizable --
14353 --------------------
14354
14355 function Is_Optimizable (N : Node_Id) return Boolean is
14356 Val : Uint;
14357 OK : Boolean;
14358 Lo : Uint;
14359 Hi : Uint;
14360 Indx : Node_Id;
ac8806c4
EB
14361 Dbl : Boolean;
14362 Ityp : Entity_Id;
0580d807
AC
14363
14364 begin
14365 if Compile_Time_Known_Value (N) then
14366 Val := Expr_Value (N);
14367
14368 if Val = Uint_0 then
22b5aff2
EB
14369 Is_Zero := True;
14370 Maybe_Superflat := False;
14371 Comp := Empty;
0580d807
AC
14372 return True;
14373
14374 elsif Val = Uint_1 then
22b5aff2
EB
14375 Is_Zero := False;
14376 Maybe_Superflat := False;
14377 Comp := Empty;
0580d807
AC
14378 return True;
14379 end if;
14380 end if;
14381
52531a62
EB
14382 -- Here we have to make sure of being within a 32-bit range (take the
14383 -- full unsigned range so the length of 32-bit arrays is accepted).
0580d807
AC
14384
14385 Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
14386
14387 if not OK
22b5aff2 14388 or else Lo < Uint_0
52531a62 14389 or else Hi > Uint_2 ** 32
0580d807
AC
14390 then
14391 return False;
14392 end if;
14393
22b5aff2
EB
14394 Maybe_Superflat := (Lo = Uint_0);
14395
ac8806c4
EB
14396 -- Tests if N is also a length attribute applied to a simple entity
14397
14398 Dbl := Is_Entity_Length (N, 2);
14399
22b5aff2
EB
14400 -- We can deal with the superflat case only if N is also a length
14401
14402 if Maybe_Superflat and then not Dbl then
14403 return False;
14404 end if;
14405
abcd9db2 14406 -- Comparison value was within range, so now we must check the index
ac8806c4 14407 -- value to make sure it is also within 32 bits.
0580d807 14408
ac8806c4
EB
14409 for K in Pos range 1 .. 2 loop
14410 Indx := First_Index (Etype (Ent (K)));
0580d807 14411
ac8806c4
EB
14412 if Present (Index (K)) then
14413 for J in 2 .. UI_To_Int (Intval (Index (K))) loop
14414 Next_Index (Indx);
14415 end loop;
14416 end if;
0580d807 14417
ac8806c4 14418 Ityp := Etype (Indx);
0580d807 14419
ac8806c4
EB
14420 if Esize (Ityp) > 32 then
14421 return False;
14422 end if;
14423
14424 exit when not Dbl;
14425 end loop;
0580d807
AC
14426
14427 Is_Zero := False;
14428 Comp := N;
14429 return True;
14430 end Is_Optimizable;
14431
22b5aff2
EB
14432 -------------------------------
14433 -- Rewrite_For_Equal_Lengths --
14434 -------------------------------
14435
14436 procedure Rewrite_For_Equal_Lengths is
14437 begin
14438 case Op is
14439 when N_Op_Eq
14440 | N_Op_Ge
14441 | N_Op_Le
14442 =>
14443 Rewrite (N,
14444 Convert_To (Typ,
14445 New_Occurrence_Of (Standard_True, Sloc (N))));
14446
14447 when N_Op_Ne
14448 | N_Op_Gt
14449 | N_Op_Lt
14450 =>
14451 Rewrite (N,
14452 Convert_To (Typ,
14453 New_Occurrence_Of (Standard_False, Sloc (N))));
14454
14455 when others =>
14456 raise Program_Error;
14457 end case;
14458
14459 Analyze_And_Resolve (N, Typ);
14460 end Rewrite_For_Equal_Lengths;
14461
0580d807
AC
14462 -- Start of processing for Optimize_Length_Comparison
14463
14464 begin
14465 -- Nothing to do if not a comparison
14466
14467 if Op not in N_Op_Compare then
14468 return;
14469 end if;
14470
f96fd197 14471 -- Nothing to do if special -gnatd.P debug flag set.
0580d807 14472
f96fd197 14473 if Debug_Flag_Dot_PP then
0580d807
AC
14474 return;
14475 end if;
14476
14477 -- Ent'Length op 0/1
14478
ac8806c4 14479 if Is_Entity_Length (Left_Opnd (N), 1)
0580d807
AC
14480 and then Is_Optimizable (Right_Opnd (N))
14481 then
14482 null;
14483
14484 -- 0/1 op Ent'Length
14485
ac8806c4 14486 elsif Is_Entity_Length (Right_Opnd (N), 1)
0580d807
AC
14487 and then Is_Optimizable (Left_Opnd (N))
14488 then
14489 -- Flip comparison to opposite sense
14490
14491 case Op is
14492 when N_Op_Lt => Op := N_Op_Gt;
14493 when N_Op_Le => Op := N_Op_Ge;
14494 when N_Op_Gt => Op := N_Op_Lt;
14495 when N_Op_Ge => Op := N_Op_Le;
14496 when others => null;
14497 end case;
14498
14499 -- Else optimization not possible
14500
14501 else
14502 return;
14503 end if;
14504
14505 -- Fall through if we will do the optimization
14506
14507 -- Cases to handle:
14508
14509 -- X'Length = 0 => X'First > X'Last
14510 -- X'Length = 1 => X'First = X'Last
14511 -- X'Length = n => X'First + (n - 1) = X'Last
14512
14513 -- X'Length /= 0 => X'First <= X'Last
14514 -- X'Length /= 1 => X'First /= X'Last
14515 -- X'Length /= n => X'First + (n - 1) /= X'Last
14516
14517 -- X'Length >= 0 => always true, warn
14518 -- X'Length >= 1 => X'First <= X'Last
14519 -- X'Length >= n => X'First + (n - 1) <= X'Last
14520
14521 -- X'Length > 0 => X'First <= X'Last
14522 -- X'Length > 1 => X'First < X'Last
14523 -- X'Length > n => X'First + (n - 1) < X'Last
14524
14525 -- X'Length <= 0 => X'First > X'Last (warn, could be =)
14526 -- X'Length <= 1 => X'First >= X'Last
14527 -- X'Length <= n => X'First + (n - 1) >= X'Last
14528
14529 -- X'Length < 0 => always false (warn)
14530 -- X'Length < 1 => X'First > X'Last
14531 -- X'Length < n => X'First + (n - 1) > X'Last
14532
14533 -- Note: for the cases of n (not constant 0,1), we require that the
14534 -- corresponding index type be integer or shorter (i.e. not 64-bit),
14535 -- and the same for the comparison value. Then we do the comparison
14536 -- using 64-bit arithmetic (actually long long integer), so that we
14537 -- cannot have overflow intefering with the result.
14538
14539 -- First deal with warning cases
14540
14541 if Is_Zero then
14542 case Op is
14543
14544 -- X'Length >= 0
14545
14546 when N_Op_Ge =>
14547 Rewrite (N,
14548 Convert_To (Typ, New_Occurrence_Of (Standard_True, Loc)));
14549 Analyze_And_Resolve (N, Typ);
14550 Warn_On_Known_Condition (N);
14551 return;
14552
14553 -- X'Length < 0
14554
14555 when N_Op_Lt =>
14556 Rewrite (N,
14557 Convert_To (Typ, New_Occurrence_Of (Standard_False, Loc)));
14558 Analyze_And_Resolve (N, Typ);
14559 Warn_On_Known_Condition (N);
14560 return;
14561
14562 when N_Op_Le =>
14563 if Constant_Condition_Warnings
14564 and then Comes_From_Source (Original_Node (N))
14565 then
324ac540 14566 Error_Msg_N ("could replace by ""'=""?c?", N);
0580d807
AC
14567 end if;
14568
14569 Op := N_Op_Eq;
14570
14571 when others =>
14572 null;
14573 end case;
14574 end if;
14575
14576 -- Build the First reference we will use
14577
14578 Left :=
14579 Make_Attribute_Reference (Loc,
ac8806c4 14580 Prefix => New_Occurrence_Of (Ent (1), Loc),
0580d807
AC
14581 Attribute_Name => Name_First);
14582
ac8806c4
EB
14583 if Present (Index (1)) then
14584 Set_Expressions (Left, New_List (New_Copy (Index (1))));
0580d807
AC
14585 end if;
14586
940eb458
EB
14587 -- Build the Last reference we will use
14588
14589 Right :=
14590 Make_Attribute_Reference (Loc,
14591 Prefix => New_Occurrence_Of (Ent (1), Loc),
14592 Attribute_Name => Name_Last);
14593
14594 if Present (Index (1)) then
14595 Set_Expressions (Right, New_List (New_Copy (Index (1))));
14596 end if;
14597
0580d807
AC
14598 -- If general value case, then do the addition of (n - 1), and
14599 -- also add the needed conversions to type Long_Long_Integer.
14600
ac8806c4
EB
14601 -- If n = Y'Length, we rewrite X'First + (n - 1) op X'Last into:
14602
14603 -- Y'Last + (X'First - Y'First) op X'Last
14604
14605 -- in the hope that X'First - Y'First can be computed statically.
14606
0580d807 14607 if Present (Comp) then
ac8806c4
EB
14608 if Present (Ent (2)) then
14609 declare
14610 Y_First : constant Node_Id :=
14611 Make_Attribute_Reference (Loc,
14612 Prefix => New_Occurrence_Of (Ent (2), Loc),
14613 Attribute_Name => Name_First);
14614 Y_Last : constant Node_Id :=
14615 Make_Attribute_Reference (Loc,
14616 Prefix => New_Occurrence_Of (Ent (2), Loc),
14617 Attribute_Name => Name_Last);
14618 R : Compare_Result;
14619
14620 begin
14621 if Present (Index (2)) then
14622 Set_Expressions (Y_First, New_List (New_Copy (Index (2))));
14623 Set_Expressions (Y_Last, New_List (New_Copy (Index (2))));
14624 end if;
14625
14626 Analyze (Left);
14627 Analyze (Y_First);
14628
940eb458
EB
14629 -- If X'First = Y'First, simplify the above formula into a
14630 -- direct comparison of Y'Last and X'Last.
ac8806c4
EB
14631
14632 R := Compile_Time_Compare (Left, Y_First, Assume_Valid => True);
14633
14634 if R = EQ then
940eb458
EB
14635 Analyze (Right);
14636 Analyze (Y_Last);
ac8806c4 14637
22b5aff2
EB
14638 R := Compile_Time_Compare
14639 (Right, Y_Last, Assume_Valid => True);
14640
14641 -- If the pairs of attributes are equal, we are done
14642
14643 if R = EQ then
14644 Rewrite_For_Equal_Lengths;
14645 return;
14646 end if;
14647
940eb458
EB
14648 -- If the base types are different, convert both operands to
14649 -- Long_Long_Integer, else compare them directly.
14650
14651 if Base_Type (Etype (Right)) /= Base_Type (Etype (Y_Last))
14652 then
14653 Left := Convert_To_Long_Long_Integer (Y_Last);
14654 else
14655 Left := Y_Last;
14656 Comp := Empty;
14657 end if;
14658
14659 -- Otherwise, use the above formula as-is
ac8806c4
EB
14660
14661 else
14662 Left :=
14663 Make_Op_Add (Loc,
22b5aff2
EB
14664 Left_Opnd =>
14665 Convert_To_Long_Long_Integer (Y_Last),
ac8806c4
EB
14666 Right_Opnd =>
14667 Make_Op_Subtract (Loc,
14668 Left_Opnd =>
14669 Convert_To_Long_Long_Integer (Left),
14670 Right_Opnd =>
14671 Convert_To_Long_Long_Integer (Y_First)));
14672 end if;
14673 end;
14674
14675 -- General value case
14676
14677 else
14678 Left :=
14679 Make_Op_Add (Loc,
14680 Left_Opnd => Convert_To_Long_Long_Integer (Left),
14681 Right_Opnd =>
14682 Make_Op_Subtract (Loc,
14683 Left_Opnd => Convert_To_Long_Long_Integer (Comp),
14684 Right_Opnd => Make_Integer_Literal (Loc, 1)));
14685 end if;
0580d807
AC
14686 end if;
14687
22b5aff2
EB
14688 -- We cannot do anything in the superflat case past this point
14689
14690 if Maybe_Superflat then
14691 return;
14692 end if;
14693
0580d807
AC
14694 -- If general operand, convert Last reference to Long_Long_Integer
14695
14696 if Present (Comp) then
ac8806c4 14697 Right := Convert_To_Long_Long_Integer (Right);
0580d807
AC
14698 end if;
14699
14700 -- Check for cases to optimize
14701
14702 -- X'Length = 0 => X'First > X'Last
14703 -- X'Length < 1 => X'First > X'Last
14704 -- X'Length < n => X'First + (n - 1) > X'Last
14705
14706 if (Is_Zero and then Op = N_Op_Eq)
14707 or else (not Is_Zero and then Op = N_Op_Lt)
14708 then
14709 Result :=
14710 Make_Op_Gt (Loc,
14711 Left_Opnd => Left,
14712 Right_Opnd => Right);
14713
14714 -- X'Length = 1 => X'First = X'Last
14715 -- X'Length = n => X'First + (n - 1) = X'Last
14716
14717 elsif not Is_Zero and then Op = N_Op_Eq then
14718 Result :=
14719 Make_Op_Eq (Loc,
14720 Left_Opnd => Left,
14721 Right_Opnd => Right);
14722
14723 -- X'Length /= 0 => X'First <= X'Last
14724 -- X'Length > 0 => X'First <= X'Last
14725
14726 elsif Is_Zero and (Op = N_Op_Ne or else Op = N_Op_Gt) then
14727 Result :=
14728 Make_Op_Le (Loc,
14729 Left_Opnd => Left,
14730 Right_Opnd => Right);
14731
14732 -- X'Length /= 1 => X'First /= X'Last
14733 -- X'Length /= n => X'First + (n - 1) /= X'Last
14734
14735 elsif not Is_Zero and then Op = N_Op_Ne then
14736 Result :=
14737 Make_Op_Ne (Loc,
14738 Left_Opnd => Left,
14739 Right_Opnd => Right);
14740
14741 -- X'Length >= 1 => X'First <= X'Last
14742 -- X'Length >= n => X'First + (n - 1) <= X'Last
14743
14744 elsif not Is_Zero and then Op = N_Op_Ge then
14745 Result :=
14746 Make_Op_Le (Loc,
14747 Left_Opnd => Left,
9dd8f36f 14748 Right_Opnd => Right);
0580d807
AC
14749
14750 -- X'Length > 1 => X'First < X'Last
14751 -- X'Length > n => X'First + (n = 1) < X'Last
14752
14753 elsif not Is_Zero and then Op = N_Op_Gt then
14754 Result :=
14755 Make_Op_Lt (Loc,
14756 Left_Opnd => Left,
14757 Right_Opnd => Right);
14758
14759 -- X'Length <= 1 => X'First >= X'Last
14760 -- X'Length <= n => X'First + (n - 1) >= X'Last
14761
14762 elsif not Is_Zero and then Op = N_Op_Le then
14763 Result :=
14764 Make_Op_Ge (Loc,
14765 Left_Opnd => Left,
14766 Right_Opnd => Right);
14767
14768 -- Should not happen at this stage
14769
14770 else
14771 raise Program_Error;
14772 end if;
14773
ac8806c4 14774 -- Rewrite and finish up (we can suppress overflow checks, see above)
0580d807
AC
14775
14776 Rewrite (N, Result);
ac8806c4 14777 Analyze_And_Resolve (N, Typ, Suppress => Overflow_Check);
0580d807
AC
14778 end Optimize_Length_Comparison;
14779
0da343bc
AC
14780 --------------------------------
14781 -- Process_If_Case_Statements --
14782 --------------------------------
14783
14784 procedure Process_If_Case_Statements (N : Node_Id; Stmts : List_Id) is
14785 Decl : Node_Id;
14786
14787 begin
14788 Decl := First (Stmts);
14789 while Present (Decl) loop
14790 if Nkind (Decl) = N_Object_Declaration
14791 and then Is_Finalizable_Transient (Decl, N)
14792 then
937e9676 14793 Process_Transient_In_Expression (Decl, N, Stmts);
0da343bc
AC
14794 end if;
14795
14796 Next (Decl);
14797 end loop;
14798 end Process_If_Case_Statements;
14799
937e9676
AC
14800 -------------------------------------
14801 -- Process_Transient_In_Expression --
14802 -------------------------------------
b2c28399 14803
937e9676
AC
14804 procedure Process_Transient_In_Expression
14805 (Obj_Decl : Node_Id;
14806 Expr : Node_Id;
14807 Stmts : List_Id)
7782ff67 14808 is
937e9676
AC
14809 Loc : constant Source_Ptr := Sloc (Obj_Decl);
14810 Obj_Id : constant Entity_Id := Defining_Identifier (Obj_Decl);
0da343bc 14811
937e9676 14812 Hook_Context : constant Node_Id := Find_Hook_Context (Expr);
4b17187f
AC
14813 -- The node on which to insert the hook as an action. This is usually
14814 -- the innermost enclosing non-transient construct.
064f4527 14815
937e9676
AC
14816 Fin_Call : Node_Id;
14817 Hook_Assign : Node_Id;
14818 Hook_Clear : Node_Id;
14819 Hook_Decl : Node_Id;
14820 Hook_Insert : Node_Id;
14821 Ptr_Decl : Node_Id;
14822
4b17187f
AC
14823 Fin_Context : Node_Id;
14824 -- The node after which to insert the finalization actions of the
937e9676 14825 -- transient object.
b2c28399 14826
8942b30c 14827 begin
4a08c95c
AC
14828 pragma Assert (Nkind (Expr) in N_Case_Expression
14829 | N_Expression_With_Actions
14830 | N_If_Expression);
7782ff67
AC
14831
14832 -- When the context is a Boolean evaluation, all three nodes capture the
14833 -- result of their computation in a local temporary:
14834
14835 -- do
14836 -- Trans_Id : Ctrl_Typ := ...;
14837 -- Result : constant Boolean := ... Trans_Id ...;
14838 -- <finalize Trans_Id>
14839 -- in Result end;
14840
937e9676
AC
14841 -- As a result, the finalization of any transient objects can safely
14842 -- take place after the result capture.
7782ff67
AC
14843
14844 -- ??? could this be extended to elementary types?
14845
937e9676 14846 if Is_Boolean_Type (Etype (Expr)) then
7782ff67
AC
14847 Fin_Context := Last (Stmts);
14848
937e9676
AC
14849 -- Otherwise the immediate context may not be safe enough to carry
14850 -- out transient object finalization due to aliasing and nesting of
14851 -- constructs. Insert calls to [Deep_]Finalize after the innermost
7782ff67
AC
14852 -- enclosing non-transient construct.
14853
8942b30c 14854 else
4b17187f 14855 Fin_Context := Hook_Context;
8942b30c 14856 end if;
064f4527 14857
937e9676
AC
14858 -- Mark the transient object as successfully processed to avoid double
14859 -- finalization.
b2c28399 14860
937e9676 14861 Set_Is_Finalized_Transient (Obj_Id);
b2c28399 14862
937e9676
AC
14863 -- Construct all the pieces necessary to hook and finalize a transient
14864 -- object.
b2c28399 14865
937e9676
AC
14866 Build_Transient_Object_Statements
14867 (Obj_Decl => Obj_Decl,
14868 Fin_Call => Fin_Call,
14869 Hook_Assign => Hook_Assign,
14870 Hook_Clear => Hook_Clear,
14871 Hook_Decl => Hook_Decl,
14872 Ptr_Decl => Ptr_Decl,
14873 Finalize_Obj => False);
b2c28399 14874
937e9676
AC
14875 -- Add the access type which provides a reference to the transient
14876 -- object. Generate:
b2c28399 14877
937e9676 14878 -- type Ptr_Typ is access all Desig_Typ;
b2c28399 14879
937e9676
AC
14880 Insert_Action (Hook_Context, Ptr_Decl);
14881
14882 -- Add the temporary which acts as a hook to the transient object.
14883 -- Generate:
b2c28399 14884
4b17187f 14885 -- Hook : Ptr_Id := null;
b2c28399 14886
937e9676 14887 Insert_Action (Hook_Context, Hook_Decl);
b2c28399 14888
937e9676
AC
14889 -- When the transient object is initialized by an aggregate, the hook
14890 -- must capture the object after the last aggregate assignment takes
14891 -- place. Only then is the object considered initialized. Generate:
b2c28399 14892
937e9676 14893 -- Hook := Ptr_Typ (Obj_Id);
b2c28399 14894 -- <or>
4b17187f 14895 -- Hook := Obj_Id'Unrestricted_Access;
b2c28399 14896
4a08c95c 14897 if Ekind (Obj_Id) in E_Constant | E_Variable
97779c34
AC
14898 and then Present (Last_Aggregate_Assignment (Obj_Id))
14899 then
4b17187f 14900 Hook_Insert := Last_Aggregate_Assignment (Obj_Id);
97779c34
AC
14901
14902 -- Otherwise the hook seizes the related object immediately
14903
14904 else
937e9676 14905 Hook_Insert := Obj_Decl;
97779c34
AC
14906 end if;
14907
937e9676 14908 Insert_After_And_Analyze (Hook_Insert, Hook_Assign);
b2c28399
AC
14909
14910 -- When the node is part of a return statement, there is no need to
14911 -- insert a finalization call, as the general finalization mechanism
937e9676
AC
14912 -- (see Build_Finalizer) would take care of the transient object on
14913 -- subprogram exit. Note that it would also be impossible to insert the
14914 -- finalization code after the return statement as this will render it
14915 -- unreachable.
b2c28399 14916
4b17187f
AC
14917 if Nkind (Fin_Context) = N_Simple_Return_Statement then
14918 null;
b2c28399 14919
937e9676
AC
14920 -- Finalize the hook after the context has been evaluated. Generate:
14921
14922 -- if Hook /= null then
14923 -- [Deep_]Finalize (Hook.all);
14924 -- Hook := null;
14925 -- end if;
b2c28399 14926
4b17187f
AC
14927 else
14928 Insert_Action_After (Fin_Context,
937e9676 14929 Make_Implicit_If_Statement (Obj_Decl,
4b17187f
AC
14930 Condition =>
14931 Make_Op_Ne (Loc,
937e9676
AC
14932 Left_Opnd =>
14933 New_Occurrence_Of (Defining_Entity (Hook_Decl), Loc),
4b17187f
AC
14934 Right_Opnd => Make_Null (Loc)),
14935
14936 Then_Statements => New_List (
937e9676
AC
14937 Fin_Call,
14938 Hook_Clear)));
b2c28399 14939 end if;
937e9676 14940 end Process_Transient_In_Expression;
b2c28399 14941
70482933
RK
14942 ------------------------
14943 -- Rewrite_Comparison --
14944 ------------------------
14945
14946 procedure Rewrite_Comparison (N : Node_Id) is
634a926b 14947 Typ : constant Entity_Id := Etype (N);
c800f862 14948
634a926b
AC
14949 False_Result : Boolean;
14950 True_Result : Boolean;
c800f862 14951
d26dc4b5
AC
14952 begin
14953 if Nkind (N) = N_Type_Conversion then
14954 Rewrite_Comparison (Expression (N));
20b5d666 14955 return;
70482933 14956
d26dc4b5 14957 elsif Nkind (N) not in N_Op_Compare then
20b5d666
JM
14958 return;
14959 end if;
70482933 14960
cc7c52c1
PT
14961 -- If both operands are static, then the comparison has been already
14962 -- folded in evaluation.
14963
14964 pragma Assert
14965 (not Is_Static_Expression (Left_Opnd (N))
14966 or else
14967 not Is_Static_Expression (Right_Opnd (N)));
14968
634a926b
AC
14969 -- Determine the potential outcome of the comparison assuming that the
14970 -- operands are valid and emit a warning when the comparison evaluates
14971 -- to True or False only in the presence of invalid values.
c800f862 14972
634a926b 14973 Warn_On_Constant_Valid_Condition (N);
70482933 14974
634a926b
AC
14975 -- Determine the potential outcome of the comparison assuming that the
14976 -- operands are not valid.
f02b8bb8 14977
634a926b
AC
14978 Test_Comparison
14979 (Op => N,
14980 Assume_Valid => False,
14981 True_Result => True_Result,
14982 False_Result => False_Result);
c800f862 14983
cc7c52c1
PT
14984 -- The outcome is a decisive False or True, rewrite the operator into a
14985 -- non-static literal.
c800f862 14986
634a926b
AC
14987 if False_Result or True_Result then
14988 Rewrite (N,
14989 Convert_To (Typ,
14990 New_Occurrence_Of (Boolean_Literals (True_Result), Sloc (N))));
c800f862 14991
634a926b 14992 Analyze_And_Resolve (N, Typ);
cc7c52c1 14993 Set_Is_Static_Expression (N, False);
634a926b
AC
14994 Warn_On_Known_Condition (N);
14995 end if;
70482933
RK
14996 end Rewrite_Comparison;
14997
fbf5a39b
AC
14998 ----------------------------
14999 -- Safe_In_Place_Array_Op --
15000 ----------------------------
15001
15002 function Safe_In_Place_Array_Op
2e071734
AC
15003 (Lhs : Node_Id;
15004 Op1 : Node_Id;
15005 Op2 : Node_Id) return Boolean
fbf5a39b
AC
15006 is
15007 Target : Entity_Id;
15008
15009 function Is_Safe_Operand (Op : Node_Id) return Boolean;
15010 -- Operand is safe if it cannot overlap part of the target of the
15011 -- operation. If the operand and the target are identical, the operand
15012 -- is safe. The operand can be empty in the case of negation.
15013
15014 function Is_Unaliased (N : Node_Id) return Boolean;
5e1c00fa 15015 -- Check that N is a stand-alone entity
fbf5a39b
AC
15016
15017 ------------------
15018 -- Is_Unaliased --
15019 ------------------
15020
15021 function Is_Unaliased (N : Node_Id) return Boolean is
15022 begin
15023 return
15024 Is_Entity_Name (N)
15025 and then No (Address_Clause (Entity (N)))
15026 and then No (Renamed_Object (Entity (N)));
15027 end Is_Unaliased;
15028
15029 ---------------------
15030 -- Is_Safe_Operand --
15031 ---------------------
15032
15033 function Is_Safe_Operand (Op : Node_Id) return Boolean is
15034 begin
15035 if No (Op) then
15036 return True;
15037
15038 elsif Is_Entity_Name (Op) then
15039 return Is_Unaliased (Op);
15040
4a08c95c 15041 elsif Nkind (Op) in N_Indexed_Component | N_Selected_Component then
fbf5a39b
AC
15042 return Is_Unaliased (Prefix (Op));
15043
15044 elsif Nkind (Op) = N_Slice then
15045 return
15046 Is_Unaliased (Prefix (Op))
15047 and then Entity (Prefix (Op)) /= Target;
15048
15049 elsif Nkind (Op) = N_Op_Not then
15050 return Is_Safe_Operand (Right_Opnd (Op));
15051
15052 else
15053 return False;
15054 end if;
15055 end Is_Safe_Operand;
15056
b6b5cca8 15057 -- Start of processing for Safe_In_Place_Array_Op
fbf5a39b
AC
15058
15059 begin
685094bf
RD
15060 -- Skip this processing if the component size is different from system
15061 -- storage unit (since at least for NOT this would cause problems).
fbf5a39b 15062
eaa826f8 15063 if Component_Size (Etype (Lhs)) /= System_Storage_Unit then
fbf5a39b
AC
15064 return False;
15065
fbf5a39b
AC
15066 -- Cannot do in place stuff if non-standard Boolean representation
15067
eaa826f8 15068 elsif Has_Non_Standard_Rep (Component_Type (Etype (Lhs))) then
fbf5a39b
AC
15069 return False;
15070
15071 elsif not Is_Unaliased (Lhs) then
15072 return False;
e7e4d230 15073
fbf5a39b
AC
15074 else
15075 Target := Entity (Lhs);
e7e4d230 15076 return Is_Safe_Operand (Op1) and then Is_Safe_Operand (Op2);
fbf5a39b
AC
15077 end if;
15078 end Safe_In_Place_Array_Op;
15079
70482933
RK
15080 -----------------------
15081 -- Tagged_Membership --
15082 -----------------------
15083
685094bf
RD
15084 -- There are two different cases to consider depending on whether the right
15085 -- operand is a class-wide type or not. If not we just compare the actual
15086 -- tag of the left expr to the target type tag:
70482933
RK
15087 --
15088 -- Left_Expr.Tag = Right_Type'Tag;
15089 --
685094bf
RD
15090 -- If it is a class-wide type we use the RT function CW_Membership which is
15091 -- usually implemented by looking in the ancestor tables contained in the
15092 -- dispatch table pointed by Left_Expr.Tag for Typ'Tag
70482933 15093
ead7594f
AC
15094 -- In both cases if Left_Expr is an access type, we first check whether it
15095 -- is null.
15096
0669bebe
GB
15097 -- Ada 2005 (AI-251): If it is a class-wide interface type we use the RT
15098 -- function IW_Membership which is usually implemented by looking in the
15099 -- table of abstract interface types plus the ancestor table contained in
15100 -- the dispatch table pointed by Left_Expr.Tag for Typ'Tag
15101
82878151
AC
15102 procedure Tagged_Membership
15103 (N : Node_Id;
15104 SCIL_Node : out Node_Id;
15105 Result : out Node_Id)
15106 is
70482933
RK
15107 Left : constant Node_Id := Left_Opnd (N);
15108 Right : constant Node_Id := Right_Opnd (N);
15109 Loc : constant Source_Ptr := Sloc (N);
15110
ead7594f 15111 -- Handle entities from the limited view
70482933 15112
ead7594f 15113 Orig_Right_Type : constant Entity_Id := Available_View (Etype (Right));
82878151 15114
ead7594f
AC
15115 Full_R_Typ : Entity_Id;
15116 Left_Type : Entity_Id := Available_View (Etype (Left));
15117 Right_Type : Entity_Id := Orig_Right_Type;
15118 Obj_Tag : Node_Id;
852dba80 15119
ead7594f
AC
15120 begin
15121 SCIL_Node := Empty;
70482933 15122
6cce2156
GD
15123 -- In the case where the type is an access type, the test is applied
15124 -- using the designated types (needed in Ada 2012 for implicit anonymous
15125 -- access conversions, for AI05-0149).
15126
15127 if Is_Access_Type (Right_Type) then
15128 Left_Type := Designated_Type (Left_Type);
15129 Right_Type := Designated_Type (Right_Type);
15130 end if;
15131
70482933
RK
15132 if Is_Class_Wide_Type (Left_Type) then
15133 Left_Type := Root_Type (Left_Type);
15134 end if;
15135
38171f43
AC
15136 if Is_Class_Wide_Type (Right_Type) then
15137 Full_R_Typ := Underlying_Type (Root_Type (Right_Type));
15138 else
15139 Full_R_Typ := Underlying_Type (Right_Type);
15140 end if;
15141
70482933
RK
15142 Obj_Tag :=
15143 Make_Selected_Component (Loc,
15144 Prefix => Relocate_Node (Left),
a9d8907c 15145 Selector_Name =>
e4494292 15146 New_Occurrence_Of (First_Tag_Component (Left_Type), Loc));
70482933 15147
6d326562 15148 if Is_Class_Wide_Type (Right_Type) then
758c442c 15149
0669bebe
GB
15150 -- No need to issue a run-time check if we statically know that the
15151 -- result of this membership test is always true. For example,
15152 -- considering the following declarations:
15153
15154 -- type Iface is interface;
15155 -- type T is tagged null record;
15156 -- type DT is new T and Iface with null record;
15157
15158 -- Obj1 : T;
15159 -- Obj2 : DT;
15160
15161 -- These membership tests are always true:
15162
15163 -- Obj1 in T'Class
15164 -- Obj2 in T'Class;
15165 -- Obj2 in Iface'Class;
15166
15167 -- We do not need to handle cases where the membership is illegal.
15168 -- For example:
15169
15170 -- Obj1 in DT'Class; -- Compile time error
15171 -- Obj1 in Iface'Class; -- Compile time error
15172
fa2538c7
JM
15173 if not Is_Interface (Left_Type)
15174 and then not Is_Class_Wide_Type (Left_Type)
4ac2477e
JM
15175 and then (Is_Ancestor (Etype (Right_Type), Left_Type,
15176 Use_Full_View => True)
533369aa
AC
15177 or else (Is_Interface (Etype (Right_Type))
15178 and then Interface_Present_In_Ancestor
761f7dcb
AC
15179 (Typ => Left_Type,
15180 Iface => Etype (Right_Type))))
0669bebe 15181 then
e4494292 15182 Result := New_Occurrence_Of (Standard_True, Loc);
82878151 15183 return;
0669bebe
GB
15184 end if;
15185
758c442c
GD
15186 -- Ada 2005 (AI-251): Class-wide applied to interfaces
15187
630d30e9
RD
15188 if Is_Interface (Etype (Class_Wide_Type (Right_Type)))
15189
0669bebe 15190 -- Support to: "Iface_CW_Typ in Typ'Class"
630d30e9
RD
15191
15192 or else Is_Interface (Left_Type)
15193 then
dfd99a80 15194 -- Issue error if IW_Membership operation not available in a
ead7594f 15195 -- configurable run-time setting.
dfd99a80
TQ
15196
15197 if not RTE_Available (RE_IW_Membership) then
b4592168
GD
15198 Error_Msg_CRT
15199 ("dynamic membership test on interface types", N);
82878151
AC
15200 Result := Empty;
15201 return;
dfd99a80
TQ
15202 end if;
15203
82878151 15204 Result :=
758c442c
GD
15205 Make_Function_Call (Loc,
15206 Name => New_Occurrence_Of (RTE (RE_IW_Membership), Loc),
15207 Parameter_Associations => New_List (
15208 Make_Attribute_Reference (Loc,
15209 Prefix => Obj_Tag,
15210 Attribute_Name => Name_Address),
e4494292 15211 New_Occurrence_Of (
38171f43 15212 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),
758c442c
GD
15213 Loc)));
15214
15215 -- Ada 95: Normal case
15216
15217 else
ead7594f
AC
15218 -- Issue error if CW_Membership operation not available in a
15219 -- configurable run-time setting.
15220
15221 if not RTE_Available (RE_CW_Membership) then
15222 Error_Msg_CRT
15223 ("dynamic membership test on tagged types", N);
15224 Result := Empty;
15225 return;
15226 end if;
15227
15228 Result :=
15229 Make_Function_Call (Loc,
15230 Name => New_Occurrence_Of (RTE (RE_CW_Membership), Loc),
15231 Parameter_Associations => New_List (
15232 Obj_Tag,
15233 New_Occurrence_Of (
15234 Node (First_Elmt (Access_Disp_Table (Full_R_Typ))),
15235 Loc)));
82878151
AC
15236
15237 -- Generate the SCIL node for this class-wide membership test.
82878151
AC
15238
15239 if Generate_SCIL then
15240 SCIL_Node := Make_SCIL_Membership_Test (Sloc (N));
15241 Set_SCIL_Entity (SCIL_Node, Etype (Right_Type));
15242 Set_SCIL_Tag_Value (SCIL_Node, Obj_Tag);
15243 end if;
758c442c
GD
15244 end if;
15245
0669bebe
GB
15246 -- Right_Type is not a class-wide type
15247
70482933 15248 else
0669bebe
GB
15249 -- No need to check the tag of the object if Right_Typ is abstract
15250
15251 if Is_Abstract_Type (Right_Type) then
e4494292 15252 Result := New_Occurrence_Of (Standard_False, Loc);
0669bebe
GB
15253
15254 else
82878151 15255 Result :=
0669bebe
GB
15256 Make_Op_Eq (Loc,
15257 Left_Opnd => Obj_Tag,
15258 Right_Opnd =>
e4494292 15259 New_Occurrence_Of
38171f43 15260 (Node (First_Elmt (Access_Disp_Table (Full_R_Typ))), Loc));
0669bebe 15261 end if;
70482933 15262 end if;
ead7594f
AC
15263
15264 -- if Left is an access object then generate test of the form:
15265 -- * if Right_Type excludes null: Left /= null and then ...
15266 -- * if Right_Type includes null: Left = null or else ...
15267
15268 if Is_Access_Type (Orig_Right_Type) then
15269 if Can_Never_Be_Null (Orig_Right_Type) then
15270 Result := Make_And_Then (Loc,
15271 Left_Opnd =>
15272 Make_Op_Ne (Loc,
15273 Left_Opnd => Left,
15274 Right_Opnd => Make_Null (Loc)),
15275 Right_Opnd => Result);
15276
15277 else
15278 Result := Make_Or_Else (Loc,
15279 Left_Opnd =>
15280 Make_Op_Eq (Loc,
15281 Left_Opnd => Left,
15282 Right_Opnd => Make_Null (Loc)),
15283 Right_Opnd => Result);
15284 end if;
15285 end if;
70482933
RK
15286 end Tagged_Membership;
15287
15288 ------------------------------
15289 -- Unary_Op_Validity_Checks --
15290 ------------------------------
15291
15292 procedure Unary_Op_Validity_Checks (N : Node_Id) is
15293 begin
15294 if Validity_Checks_On and Validity_Check_Operands then
15295 Ensure_Valid (Right_Opnd (N));
15296 end if;
15297 end Unary_Op_Validity_Checks;
15298
15299end Exp_Ch4;