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