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