]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ada/exp_util.adb
[Ada] Variable-sized node types
[thirdparty/gcc.git] / gcc / ada / exp_util.adb
CommitLineData
70482933
RK
1------------------------------------------------------------------------------
2-- --
3-- GNAT COMPILER COMPONENTS --
4-- --
5-- E X P _ U T I L --
6-- --
7-- B o d y --
8-- --
8d0d46f4 9-- Copyright (C) 1992-2021, Free Software Foundation, Inc. --
70482933
RK
10-- --
11-- GNAT is free software; you can redistribute it and/or modify it under --
12-- terms of the GNU General Public License as published by the Free Soft- --
b5c84c3c 13-- ware Foundation; either version 3, or (at your option) any later ver- --
70482933
RK
14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17-- for more details. You should have received a copy of the GNU General --
b5c84c3c
RD
18-- Public License distributed with GNAT; see file COPYING3. If not, go to --
19-- http://www.gnu.org/licenses for a complete copy of the license. --
70482933
RK
20-- --
21-- GNAT was originally developed by the GNAT team at New York University. --
71ff80dc 22-- Extensive contributions were provided by Ada Core Technologies Inc. --
70482933
RK
23-- --
24------------------------------------------------------------------------------
25
2f7b7467 26with Aspects; use Aspects;
70482933 27with Atree; use Atree;
afbcdf5e 28with Casing; use Casing;
70482933 29with Checks; use Checks;
59e54267 30with Debug; use Debug;
76f9c7f4
BD
31with Einfo; use Einfo;
32with Einfo.Entities; use Einfo.Entities;
33with Einfo.Utils; use Einfo.Utils;
70482933
RK
34with Elists; use Elists;
35with Errout; use Errout;
f44fe430 36with Exp_Aggr; use Exp_Aggr;
86cde7b1 37with Exp_Ch6; use Exp_Ch6;
70482933 38with Exp_Ch7; use Exp_Ch7;
bb072d1c 39with Exp_Ch11; use Exp_Ch11;
241ebe89 40with Ghost; use Ghost;
70482933
RK
41with Inline; use Inline;
42with Itypes; use Itypes;
43with Lib; use Lib;
70482933
RK
44with Nlists; use Nlists;
45with Nmake; use Nmake;
46with Opt; use Opt;
47with Restrict; use Restrict;
6e937c1c 48with Rident; use Rident;
70482933 49with Sem; use Sem;
a4100e55 50with Sem_Aux; use Sem_Aux;
f63d601b
HK
51with Sem_Ch3; use Sem_Ch3;
52with Sem_Ch6; use Sem_Ch6;
70482933 53with Sem_Ch8; use Sem_Ch8;
f63d601b 54with Sem_Ch12; use Sem_Ch12;
88fa9a24 55with Sem_Ch13; use Sem_Ch13;
f63d601b 56with Sem_Disp; use Sem_Disp;
90e491a7 57with Sem_Elab; use Sem_Elab;
70482933
RK
58with Sem_Eval; use Sem_Eval;
59with Sem_Res; use Sem_Res;
758c442c 60with Sem_Type; use Sem_Type;
70482933 61with Sem_Util; use Sem_Util;
76f9c7f4 62with Sinfo.Utils; use Sinfo.Utils;
fbf5a39b 63with Snames; use Snames;
70482933
RK
64with Stand; use Stand;
65with Stringt; use Stringt;
66with Tbuild; use Tbuild;
67with Ttypes; use Ttypes;
70482933
RK
68with Validsw; use Validsw;
69
851e9f19 70with GNAT.HTable;
70482933
RK
71package body Exp_Util is
72
f63d601b
HK
73 ---------------------------------------------------------
74 -- Handling of inherited class-wide pre/postconditions --
75 ---------------------------------------------------------
76
77 -- Following AI12-0113, the expression for a class-wide condition is
78 -- transformed for a subprogram that inherits it, by replacing calls
79 -- to primitive operations of the original controlling type into the
80 -- corresponding overriding operations of the derived type. The following
81 -- hash table manages this mapping, and is expanded on demand whenever
82 -- such inherited expression needs to be constructed.
83
84 -- The mapping is also used to check whether an inherited operation has
85 -- a condition that depends on overridden operations. For such an
86 -- operation we must create a wrapper that is then treated as a normal
87 -- overriding. In SPARK mode such operations are illegal.
88
89 -- For a given root type there may be several type extensions with their
90 -- own overriding operations, so at various times a given operation of
91 -- the root will be mapped into different overridings. The root type is
92 -- also mapped into the current type extension to indicate that its
93 -- operations are mapped into the overriding operations of that current
94 -- type extension.
95
b619c88e 96 -- The contents of the map are as follows:
f63d601b 97
b619c88e 98 -- Key Value
f63d601b 99
b619c88e
AC
100 -- Discriminant (Entity_Id) Discriminant (Entity_Id)
101 -- Discriminant (Entity_Id) Non-discriminant name (Entity_Id)
102 -- Discriminant (Entity_Id) Expression (Node_Id)
103 -- Primitive subprogram (Entity_Id) Primitive subprogram (Entity_Id)
104 -- Type (Entity_Id) Type (Entity_Id)
105
106 Type_Map_Size : constant := 511;
107
108 subtype Type_Map_Header is Integer range 0 .. Type_Map_Size - 1;
109 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header;
110
111 package Type_Map is new GNAT.HTable.Simple_HTable
112 (Header_Num => Type_Map_Header,
f63d601b 113 Key => Entity_Id,
b619c88e 114 Element => Node_Or_Entity_Id,
f63d601b 115 No_element => Empty,
b619c88e 116 Hash => Type_Map_Hash,
f63d601b
HK
117 Equal => "=");
118
70482933
RK
119 -----------------------
120 -- Local Subprograms --
121 -----------------------
122
123 function Build_Task_Array_Image
124 (Loc : Source_Ptr;
125 Id_Ref : Node_Id;
7bc1c7df 126 A_Type : Entity_Id;
bebbff91 127 Dyn : Boolean := False) return Node_Id;
273adcdf
AC
128 -- Build function to generate the image string for a task that is an array
129 -- component, concatenating the images of each index. To avoid storage
130 -- leaks, the string is built with successive slice assignments. The flag
131 -- Dyn indicates whether this is called for the initialization procedure of
132 -- an array of tasks, or for the name of a dynamically created task that is
133 -- assigned to an indexed component.
70482933
RK
134
135 function Build_Task_Image_Function
136 (Loc : Source_Ptr;
137 Decls : List_Id;
138 Stats : List_Id;
bebbff91 139 Res : Entity_Id) return Node_Id;
273adcdf
AC
140 -- Common processing for Task_Array_Image and Task_Record_Image. Build
141 -- function body that computes image.
70482933
RK
142
143 procedure Build_Task_Image_Prefix
144 (Loc : Source_Ptr;
145 Len : out Entity_Id;
146 Res : out Entity_Id;
147 Pos : out Entity_Id;
148 Prefix : Entity_Id;
149 Sum : Node_Id;
86cde7b1
RD
150 Decls : List_Id;
151 Stats : List_Id);
273adcdf
AC
152 -- Common processing for Task_Array_Image and Task_Record_Image. Create
153 -- local variables and assign prefix of name to result string.
70482933
RK
154
155 function Build_Task_Record_Image
156 (Loc : Source_Ptr;
157 Id_Ref : Node_Id;
bebbff91 158 Dyn : Boolean := False) return Node_Id;
273adcdf
AC
159 -- Build function to generate the image string for a task that is a record
160 -- component. Concatenate name of variable with that of selector. The flag
161 -- Dyn indicates whether this is called for the initialization procedure of
162 -- record with task components, or for a dynamically created task that is
163 -- assigned to a selected component.
70482933 164
08cd7c2f
AC
165 procedure Evaluate_Slice_Bounds (Slice : Node_Id);
166 -- Force evaluation of bounds of a slice, which may be given by a range
167 -- or by a subtype indication with or without a constraint.
168
b3801819
PMR
169 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean;
170 -- Determine whether pragma Default_Initial_Condition denoted by Prag has
171 -- an assertion expression that should be verified at run time.
172
a46fa651
ES
173 function Is_Uninitialized_Aggregate
174 (Exp : Node_Id;
175 T : Entity_Id) return Boolean;
176 -- Determine whether an array aggregate used in an object declaration
177 -- is uninitialized, when the aggregate is declared with a box and
178 -- the component type has no default value. Such an aggregate can be
179 -- optimized away to prevent the copying of uninitialized data, and
180 -- the bounds of the aggregate can be propagated directly to the
181 -- object declaration.
182
70482933 183 function Make_CW_Equivalent_Type
bebbff91
AC
184 (T : Entity_Id;
185 E : Node_Id) return Entity_Id;
70482933 186 -- T is a class-wide type entity, E is the initial expression node that
273adcdf
AC
187 -- constrains T in case such as: " X: T := E" or "new T'(E)". This function
188 -- returns the entity of the Equivalent type and inserts on the fly the
189 -- necessary declaration such as:
fbf5a39b 190 --
70482933
RK
191 -- type anon is record
192 -- _parent : Root_Type (T); constrained with E discriminants (if any)
193 -- Extension : String (1 .. expr to match size of E);
194 -- end record;
195 --
273adcdf
AC
196 -- This record is compatible with any object of the class of T thanks to
197 -- the first field and has the same size as E thanks to the second.
70482933
RK
198
199 function Make_Literal_Range
200 (Loc : Source_Ptr;
bebbff91 201 Literal_Typ : Entity_Id) return Node_Id;
70482933 202 -- Produce a Range node whose bounds are:
f91b40db 203 -- Low_Bound (Literal_Type) ..
86cde7b1 204 -- Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1)
70482933 205 -- this is used for expanding declarations like X : String := "sdfgdfg";
86cde7b1
RD
206 --
207 -- If the index type of the target array is not integer, we generate:
208 -- Low_Bound (Literal_Type) ..
209 -- Literal_Type'Val
210 -- (Literal_Type'Pos (Low_Bound (Literal_Type))
211 -- + (Length (Literal_Typ) -1))
70482933 212
b3b9865d
AC
213 function Make_Non_Empty_Check
214 (Loc : Source_Ptr;
215 N : Node_Id) return Node_Id;
216 -- Produce a boolean expression checking that the unidimensional array
217 -- node N is not empty.
218
70482933
RK
219 function New_Class_Wide_Subtype
220 (CW_Typ : Entity_Id;
bebbff91
AC
221 N : Node_Id) return Entity_Id;
222 -- Create an implicit subtype of CW_Typ attached to node N
70482933 223
87729e5a 224 function Requires_Cleanup_Actions
2ba7e31e 225 (L : List_Id;
fcf848c4 226 Lib_Level : Boolean;
2ba7e31e 227 Nested_Constructs : Boolean) return Boolean;
87729e5a
AC
228 -- Given a list L, determine whether it contains one of the following:
229 --
230 -- 1) controlled objects
231 -- 2) library-level tagged types
232 --
5f44f0d4
AC
233 -- Lib_Level is True when the list comes from a construct at the library
234 -- level, and False otherwise. Nested_Constructs is True when any nested
235 -- packages declared in L must be processed, and False otherwise.
87729e5a 236
cf9e3829
EB
237 function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean;
238 -- Return True if the evaluation of the given attribute is considered
239 -- side-effect free, independently of its prefix and expressions.
240
4c318253
AC
241 -------------------------------------
242 -- Activate_Atomic_Synchronization --
243 -------------------------------------
244
245 procedure Activate_Atomic_Synchronization (N : Node_Id) is
246 Msg_Node : Node_Id;
247
248 begin
73fe1679 249 case Nkind (Parent (N)) is
73fe1679 250
d8f43ee6
HK
251 -- Check for cases of appearing in the prefix of a construct where we
252 -- don't need atomic synchronization for this kind of usage.
6ec084f3
HK
253
254 when
d8f43ee6
HK
255 -- Nothing to do if we are the prefix of an attribute, since we
256 -- do not want an atomic sync operation for things like 'Size.
6ec084f3 257
d8f43ee6 258 N_Attribute_Reference
6ec084f3 259
d8f43ee6 260 -- The N_Reference node is like an attribute
73fe1679 261
d8f43ee6 262 | N_Reference
73fe1679 263
d8f43ee6
HK
264 -- Nothing to do for a reference to a component (or components)
265 -- of a composite object. Only reads and updates of the object
266 -- as a whole require atomic synchronization (RM C.6 (15)).
73fe1679 267
d8f43ee6
HK
268 | N_Indexed_Component
269 | N_Selected_Component
270 | N_Slice
271 =>
6ec084f3 272 -- For all the above cases, nothing to do if we are the prefix
73fe1679
AC
273
274 if Prefix (Parent (N)) = N then
275 return;
276 end if;
277
d8f43ee6
HK
278 when others =>
279 null;
73fe1679 280 end case;
4c318253 281
6333ad3d 282 -- Nothing to do for the identifier in an object renaming declaration,
47b79f78 283 -- the renaming itself does not need atomic synchronization.
6333ad3d
AC
284
285 if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
286 return;
287 end if;
288
4c318253
AC
289 -- Go ahead and set the flag
290
291 Set_Atomic_Sync_Required (N);
292
293 -- Generate info message if requested
294
295 if Warn_On_Atomic_Synchronization then
296 case Nkind (N) is
297 when N_Identifier =>
298 Msg_Node := N;
299
d8f43ee6
HK
300 when N_Expanded_Name
301 | N_Selected_Component
302 =>
4c318253
AC
303 Msg_Node := Selector_Name (N);
304
d8f43ee6
HK
305 when N_Explicit_Dereference
306 | N_Indexed_Component
307 =>
4c318253
AC
308 Msg_Node := Empty;
309
310 when others =>
311 pragma Assert (False);
312 return;
313 end case;
314
315 if Present (Msg_Node) then
324ac540 316 Error_Msg_N
2e57f88b 317 ("info: atomic synchronization set for &?N?", Msg_Node);
4c318253 318 else
324ac540 319 Error_Msg_N
2e57f88b 320 ("info: atomic synchronization set?N?", N);
4c318253
AC
321 end if;
322 end if;
323 end Activate_Atomic_Synchronization;
324
70482933
RK
325 ----------------------
326 -- Adjust_Condition --
327 ----------------------
328
329 procedure Adjust_Condition (N : Node_Id) is
330 begin
331 if No (N) then
332 return;
333 end if;
334
335 declare
336 Loc : constant Source_Ptr := Sloc (N);
337 T : constant Entity_Id := Etype (N);
70482933
RK
338
339 begin
a2773bd3
AC
340 -- Defend against a call where the argument has no type, or has a
341 -- type that is not Boolean. This can occur because of prior errors.
70482933
RK
342
343 if No (T) or else not Is_Boolean_Type (T) then
344 return;
345 end if;
346
347 -- Apply validity checking if needed
348
349 if Validity_Checks_On and Validity_Check_Tests then
350 Ensure_Valid (N);
351 end if;
352
353 -- Immediate return if standard boolean, the most common case,
354 -- where nothing needs to be done.
355
356 if Base_Type (T) = Standard_Boolean then
357 return;
358 end if;
359
3f833dc2 360 -- Case of zero/nonzero semantics or nonstandard enumeration
70482933
RK
361 -- representation. In each case, we rewrite the node as:
362
363 -- ityp!(N) /= False'Enum_Rep
364
273adcdf
AC
365 -- where ityp is an integer type with large enough size to hold any
366 -- value of type T.
70482933
RK
367
368 if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then
70482933
RK
369 Rewrite (N,
370 Make_Op_Ne (Loc,
c7c7dd3a
EB
371 Left_Opnd =>
372 Unchecked_Convert_To
373 (Integer_Type_For (Esize (T), Uns => False), N),
70482933
RK
374 Right_Opnd =>
375 Make_Attribute_Reference (Loc,
376 Attribute_Name => Name_Enum_Rep,
377 Prefix =>
378 New_Occurrence_Of (First_Literal (T), Loc))));
379 Analyze_And_Resolve (N, Standard_Boolean);
380
381 else
382 Rewrite (N, Convert_To (Standard_Boolean, N));
383 Analyze_And_Resolve (N, Standard_Boolean);
384 end if;
385 end;
386 end Adjust_Condition;
387
388 ------------------------
389 -- Adjust_Result_Type --
390 ------------------------
391
392 procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is
393 begin
394 -- Ignore call if current type is not Standard.Boolean
395
396 if Etype (N) /= Standard_Boolean then
397 return;
398 end if;
399
400 -- If result is already of correct type, nothing to do. Note that
401 -- this will get the most common case where everything has a type
402 -- of Standard.Boolean.
403
404 if Base_Type (T) = Standard_Boolean then
405 return;
406
407 else
408 declare
409 KP : constant Node_Kind := Nkind (Parent (N));
410
411 begin
412 -- If result is to be used as a Condition in the syntax, no need
413 -- to convert it back, since if it was changed to Standard.Boolean
414 -- using Adjust_Condition, that is just fine for this usage.
415
416 if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then
417 return;
418
419 -- If result is an operand of another logical operation, no need
420 -- to reset its type, since Standard.Boolean is just fine, and
421 -- such operations always do Adjust_Condition on their operands.
422
ac7120ce
RD
423 elsif KP in N_Op_Boolean
424 or else KP in N_Short_Circuit
70482933
RK
425 or else KP = N_Op_Not
426 then
427 return;
428
273adcdf 429 -- Otherwise we perform a conversion from the current type, which
f24ea912
AC
430 -- must be Standard.Boolean, to the desired type. Use the base
431 -- type to prevent spurious constraint checks that are extraneous
432 -- to the transformation. The type and its base have the same
433 -- representation, standard or otherwise.
70482933
RK
434
435 else
436 Set_Analyzed (N);
f24ea912
AC
437 Rewrite (N, Convert_To (Base_Type (T), N));
438 Analyze_And_Resolve (N, Base_Type (T));
70482933
RK
439 end if;
440 end;
441 end if;
442 end Adjust_Result_Type;
443
444 --------------------------
445 -- Append_Freeze_Action --
446 --------------------------
447
448 procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is
05350ac6 449 Fnode : Node_Id;
70482933
RK
450
451 begin
452 Ensure_Freeze_Node (T);
453 Fnode := Freeze_Node (T);
454
59e54267 455 if No (Actions (Fnode)) then
3a3af4c3
AC
456 Set_Actions (Fnode, New_List (N));
457 else
458 Append (N, Actions (Fnode));
70482933
RK
459 end if;
460
70482933
RK
461 end Append_Freeze_Action;
462
463 ---------------------------
464 -- Append_Freeze_Actions --
465 ---------------------------
466
467 procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is
3a3af4c3 468 Fnode : Node_Id;
70482933
RK
469
470 begin
471 if No (L) then
472 return;
3a3af4c3
AC
473 end if;
474
475 Ensure_Freeze_Node (T);
476 Fnode := Freeze_Node (T);
70482933 477
3a3af4c3
AC
478 if No (Actions (Fnode)) then
479 Set_Actions (Fnode, L);
70482933 480 else
3a3af4c3 481 Append_List (L, Actions (Fnode));
70482933
RK
482 end if;
483 end Append_Freeze_Actions;
484
6b0c5c72
PT
485 ----------------------------------------
486 -- Attribute_Constrained_Static_Value --
487 ----------------------------------------
d2880e69
CD
488
489 function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean
490 is
491 Ptyp : constant Entity_Id := Etype (Pref);
492 Formal_Ent : constant Entity_Id := Param_Entity (Pref);
493
494 function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean;
495 -- Ada 2005 (AI-363): Returns True if the object name Obj denotes a
496 -- view of an aliased object whose subtype is constrained.
497
498 ---------------------------------
499 -- Is_Constrained_Aliased_View --
500 ---------------------------------
501
502 function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is
503 E : Entity_Id;
504
505 begin
506 if Is_Entity_Name (Obj) then
507 E := Entity (Obj);
508
509 if Present (Renamed_Object (E)) then
510 return Is_Constrained_Aliased_View (Renamed_Object (E));
511 else
512 return Is_Aliased (E) and then Is_Constrained (Etype (E));
513 end if;
514
515 else
516 return Is_Aliased_View (Obj)
517 and then
518 (Is_Constrained (Etype (Obj))
519 or else
520 (Nkind (Obj) = N_Explicit_Dereference
521 and then
522 not Object_Type_Has_Constrained_Partial_View
523 (Typ => Base_Type (Etype (Obj)),
524 Scop => Current_Scope)));
525 end if;
526 end Is_Constrained_Aliased_View;
527
528 -- Start of processing for Attribute_Constrained_Static_Value
529
530 begin
531 -- We are in a case where the attribute is known statically, and
532 -- implicit dereferences have been rewritten.
533
534 pragma Assert
535 (not (Present (Formal_Ent)
536 and then Ekind (Formal_Ent) /= E_Constant
537 and then Present (Extra_Constrained (Formal_Ent)))
538 and then
539 not (Is_Access_Type (Etype (Pref))
540 and then (not Is_Entity_Name (Pref)
541 or else Is_Object (Entity (Pref))))
542 and then
543 not (Nkind (Pref) = N_Identifier
544 and then Ekind (Entity (Pref)) = E_Variable
545 and then Present (Extra_Constrained (Entity (Pref)))));
546
547 if Is_Entity_Name (Pref) then
548 declare
6b0c5c72 549 Ent : constant Entity_Id := Entity (Pref);
d2880e69
CD
550 Res : Boolean;
551
552 begin
553 -- (RM J.4) obsolescent cases
554
555 if Is_Type (Ent) then
556
557 -- Private type
558
559 if Is_Private_Type (Ent) then
560 Res := not Has_Discriminants (Ent)
561 or else Is_Constrained (Ent);
562
563 -- It not a private type, must be a generic actual type
564 -- that corresponded to a private type. We know that this
565 -- correspondence holds, since otherwise the reference
566 -- within the generic template would have been illegal.
567
568 else
569 if Is_Composite_Type (Underlying_Type (Ent)) then
570 Res := Is_Constrained (Ent);
571 else
572 Res := True;
573 end if;
574 end if;
575
576 else
577
578 -- If the prefix is not a variable or is aliased, then
579 -- definitely true; if it's a formal parameter without an
580 -- associated extra formal, then treat it as constrained.
581
582 -- Ada 2005 (AI-363): An aliased prefix must be known to be
583 -- constrained in order to set the attribute to True.
584
585 if not Is_Variable (Pref)
586 or else Present (Formal_Ent)
587 or else (Ada_Version < Ada_2005
588 and then Is_Aliased_View (Pref))
589 or else (Ada_Version >= Ada_2005
590 and then Is_Constrained_Aliased_View (Pref))
591 then
592 Res := True;
593
594 -- Variable case, look at type to see if it is constrained.
595 -- Note that the one case where this is not accurate (the
596 -- procedure formal case), has been handled above.
597
598 -- We use the Underlying_Type here (and below) in case the
599 -- type is private without discriminants, but the full type
600 -- has discriminants. This case is illegal, but we generate
601 -- it internally for passing to the Extra_Constrained
602 -- parameter.
603
604 else
605 -- In Ada 2012, test for case of a limited tagged type,
606 -- in which case the attribute is always required to
607 -- return True. The underlying type is tested, to make
608 -- sure we also return True for cases where there is an
609 -- unconstrained object with an untagged limited partial
610 -- view which has defaulted discriminants (such objects
611 -- always produce a False in earlier versions of
612 -- Ada). (Ada 2012: AI05-0214)
613
614 Res :=
615 Is_Constrained (Underlying_Type (Etype (Ent)))
616 or else
617 (Ada_Version >= Ada_2012
618 and then Is_Tagged_Type (Underlying_Type (Ptyp))
619 and then Is_Limited_Type (Ptyp));
620 end if;
621 end if;
622
623 return Res;
624 end;
625
626 -- Prefix is not an entity name. These are also cases where we can
627 -- always tell at compile time by looking at the form and type of the
628 -- prefix. If an explicit dereference of an object with constrained
629 -- partial view, this is unconstrained (Ada 2005: AI95-0363). If the
630 -- underlying type is a limited tagged type, then Constrained is
631 -- required to always return True (Ada 2012: AI05-0214).
632
633 else
634 return not Is_Variable (Pref)
635 or else
636 (Nkind (Pref) = N_Explicit_Dereference
637 and then
638 not Object_Type_Has_Constrained_Partial_View
639 (Typ => Base_Type (Ptyp),
640 Scop => Current_Scope))
641 or else Is_Constrained (Underlying_Type (Ptyp))
642 or else (Ada_Version >= Ada_2012
643 and then Is_Tagged_Type (Underlying_Type (Ptyp))
644 and then Is_Limited_Type (Ptyp));
645 end if;
646 end Attribute_Constrained_Static_Value;
647
df3e68b1
HK
648 ------------------------------------
649 -- Build_Allocate_Deallocate_Proc --
650 ------------------------------------
651
652 procedure Build_Allocate_Deallocate_Proc
653 (N : Node_Id;
654 Is_Allocate : Boolean)
655 is
df3e68b1
HK
656 function Find_Object (E : Node_Id) return Node_Id;
657 -- Given an arbitrary expression of an allocator, try to find an object
658 -- reference in it, otherwise return the original expression.
659
660 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean;
661 -- Determine whether subprogram Subp denotes a custom allocate or
662 -- deallocate.
663
664 -----------------
665 -- Find_Object --
666 -----------------
667
668 function Find_Object (E : Node_Id) return Node_Id is
2c1b72d7 669 Expr : Node_Id;
df3e68b1
HK
670
671 begin
672 pragma Assert (Is_Allocate);
673
2c1b72d7
AC
674 Expr := E;
675 loop
31d922e3
AC
676 if Nkind (Expr) = N_Explicit_Dereference then
677 Expr := Prefix (Expr);
678
679 elsif Nkind (Expr) = N_Qualified_Expression then
2c1b72d7 680 Expr := Expression (Expr);
df3e68b1 681
31d922e3
AC
682 elsif Nkind (Expr) = N_Unchecked_Type_Conversion then
683
684 -- When interface class-wide types are involved in allocation,
685 -- the expander introduces several levels of address arithmetic
686 -- to perform dispatch table displacement. In this scenario the
687 -- object appears as:
f3920a13 688
31d922e3 689 -- Tag_Ptr (Base_Address (<object>'Address))
f3920a13 690
31d922e3
AC
691 -- Detect this case and utilize the whole expression as the
692 -- "object" since it now points to the proper dispatch table.
693
694 if Is_RTE (Etype (Expr), RE_Tag_Ptr) then
695 exit;
696
697 -- Continue to strip the object
698
699 else
700 Expr := Expression (Expr);
701 end if;
2c1b72d7
AC
702
703 else
704 exit;
df3e68b1
HK
705 end if;
706 end loop;
707
708 return Expr;
709 end Find_Object;
710
711 ---------------------------------
712 -- Is_Allocate_Deallocate_Proc --
713 ---------------------------------
714
715 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is
716 begin
717 -- Look for a subprogram body with only one statement which is a
d3f70b35 718 -- call to Allocate_Any_Controlled / Deallocate_Any_Controlled.
df3e68b1
HK
719
720 if Ekind (Subp) = E_Procedure
721 and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body
722 then
723 declare
724 HSS : constant Node_Id :=
725 Handled_Statement_Sequence (Parent (Parent (Subp)));
726 Proc : Entity_Id;
727
728 begin
729 if Present (Statements (HSS))
730 and then Nkind (First (Statements (HSS))) =
731 N_Procedure_Call_Statement
732 then
733 Proc := Entity (Name (First (Statements (HSS))));
734
735 return
d3f70b35
AC
736 Is_RTE (Proc, RE_Allocate_Any_Controlled)
737 or else Is_RTE (Proc, RE_Deallocate_Any_Controlled);
df3e68b1
HK
738 end if;
739 end;
740 end if;
741
742 return False;
743 end Is_Allocate_Deallocate_Proc;
744
d1eb8a82
AC
745 -- Local variables
746
4c5e9870
SB
747 Desig_Typ : Entity_Id;
748 Expr : Node_Id;
749 Needs_Fin : Boolean;
750 Pool_Id : Entity_Id;
751 Proc_To_Call : Node_Id := Empty;
752 Ptr_Typ : Entity_Id;
753 Use_Secondary_Stack_Pool : Boolean;
d1eb8a82 754
df3e68b1
HK
755 -- Start of processing for Build_Allocate_Deallocate_Proc
756
757 begin
ca5af305
AC
758 -- Obtain the attributes of the allocation / deallocation
759
760 if Nkind (N) = N_Free_Statement then
761 Expr := Expression (N);
762 Ptr_Typ := Base_Type (Etype (Expr));
763 Proc_To_Call := Procedure_To_Call (N);
764
765 else
766 if Nkind (N) = N_Object_Declaration then
767 Expr := Expression (N);
768 else
769 Expr := N;
770 end if;
771
f7bb41af
AC
772 -- In certain cases an allocator with a qualified expression may
773 -- be relocated and used as the initialization expression of a
774 -- temporary:
775
776 -- before:
777 -- Obj : Ptr_Typ := new Desig_Typ'(...);
778
779 -- after:
780 -- Tmp : Ptr_Typ := new Desig_Typ'(...);
781 -- Obj : Ptr_Typ := Tmp;
782
783 -- Since the allocator is always marked as analyzed to avoid infinite
784 -- expansion, it will never be processed by this routine given that
785 -- the designated type needs finalization actions. Detect this case
786 -- and complete the expansion of the allocator.
787
788 if Nkind (Expr) = N_Identifier
789 and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration
790 and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator
791 then
792 Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True);
793 return;
794 end if;
ca5af305 795
f7bb41af
AC
796 -- The allocator may have been rewritten into something else in which
797 -- case the expansion performed by this routine does not apply.
ca5af305 798
f7bb41af
AC
799 if Nkind (Expr) /= N_Allocator then
800 return;
ca5af305 801 end if;
f7bb41af
AC
802
803 Ptr_Typ := Base_Type (Etype (Expr));
804 Proc_To_Call := Procedure_To_Call (Expr);
ca5af305
AC
805 end if;
806
807 Pool_Id := Associated_Storage_Pool (Ptr_Typ);
808 Desig_Typ := Available_View (Designated_Type (Ptr_Typ));
df3e68b1 809
ca5af305
AC
810 -- Handle concurrent types
811
812 if Is_Concurrent_Type (Desig_Typ)
813 and then Present (Corresponding_Record_Type (Desig_Typ))
814 then
815 Desig_Typ := Corresponding_Record_Type (Desig_Typ);
816 end if;
817
4c5e9870
SB
818 Use_Secondary_Stack_Pool :=
819 Is_RTE (Pool_Id, RE_SS_Pool)
820 or else (Nkind (Expr) = N_Allocator
821 and then Is_RTE (Storage_Pool (Expr), RE_SS_Pool));
822
ca5af305
AC
823 -- Do not process allocations / deallocations without a pool
824
825 if No (Pool_Id) then
df3e68b1
HK
826 return;
827
ca5af305 828 -- Do not process allocations on / deallocations from the secondary
4c5e9870 829 -- stack, except for access types used to implement indirect temps.
ca5af305 830
4c5e9870
SB
831 elsif Use_Secondary_Stack_Pool
832 and then not Old_Attr_Util.Indirect_Temps
833 .Is_Access_Type_For_Indirect_Temp (Ptr_Typ)
d4dfb005 834 then
ca5af305
AC
835 return;
836
fc3819c9
AC
837 -- Optimize the case where we are using the default Global_Pool_Object,
838 -- and we don't need the heavy finalization machinery.
839
3477e0b2 840 elsif Is_RTE (Pool_Id, RE_Global_Pool_Object)
fc3819c9
AC
841 and then not Needs_Finalization (Desig_Typ)
842 then
843 return;
844
ca5af305
AC
845 -- Do not replicate the machinery if the allocator / free has already
846 -- been expanded and has a custom Allocate / Deallocate.
847
848 elsif Present (Proc_To_Call)
849 and then Is_Allocate_Deallocate_Proc (Proc_To_Call)
850 then
851 return;
852 end if;
853
d1eb8a82
AC
854 -- Finalization actions are required when the object to be allocated or
855 -- deallocated needs these actions and the associated access type is not
856 -- subject to pragma No_Heap_Finalization.
857
858 Needs_Fin :=
859 Needs_Finalization (Desig_Typ)
860 and then not No_Heap_Finalization (Ptr_Typ);
861
862 if Needs_Fin then
ca5af305 863
ca5af305
AC
864 -- Do nothing if the access type may never allocate / deallocate
865 -- objects.
866
7d1d3a54 867 if No_Pool_Assigned (Ptr_Typ) then
ca5af305 868 return;
ca5af305
AC
869 end if;
870
871 -- The allocation / deallocation of a controlled object must be
872 -- chained on / detached from a finalization master.
873
874 pragma Assert (Present (Finalization_Master (Ptr_Typ)));
875
876 -- The only other kind of allocation / deallocation supported by this
877 -- routine is on / from a subpool.
df3e68b1
HK
878
879 elsif Nkind (Expr) = N_Allocator
ca5af305 880 and then No (Subpool_Handle_Name (Expr))
df3e68b1
HK
881 then
882 return;
883 end if;
884
885 declare
886 Loc : constant Source_Ptr := Sloc (N);
887 Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A');
888 Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L');
889 Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P');
890 Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S');
891
892 Actuals : List_Id;
d3f70b35
AC
893 Fin_Addr_Id : Entity_Id;
894 Fin_Mas_Act : Node_Id;
895 Fin_Mas_Id : Entity_Id;
df3e68b1 896 Proc_To_Call : Entity_Id;
ca5af305 897 Subpool : Node_Id := Empty;
df3e68b1
HK
898
899 begin
d3f70b35
AC
900 -- Step 1: Construct all the actuals for the call to library routine
901 -- Allocate_Any_Controlled / Deallocate_Any_Controlled.
df3e68b1 902
d3f70b35 903 -- a) Storage pool
df3e68b1 904
e4494292 905 Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc));
df3e68b1 906
d3f70b35 907 if Is_Allocate then
df3e68b1 908
d3f70b35 909 -- b) Subpool
df3e68b1 910
ca5af305
AC
911 if Nkind (Expr) = N_Allocator then
912 Subpool := Subpool_Handle_Name (Expr);
913 end if;
914
4bb43ffb
AC
915 -- If a subpool is present it can be an arbitrary name, so make
916 -- the actual by copying the tree.
917
ca5af305 918 if Present (Subpool) then
4bb43ffb 919 Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
d3f70b35
AC
920 else
921 Append_To (Actuals, Make_Null (Loc));
922 end if;
df3e68b1 923
d3f70b35
AC
924 -- c) Finalization master
925
d1eb8a82 926 if Needs_Fin then
ca5af305 927 Fin_Mas_Id := Finalization_Master (Ptr_Typ);
e4494292 928 Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc);
d3f70b35
AC
929
930 -- Handle the case where the master is actually a pointer to a
931 -- master. This case arises in build-in-place functions.
932
933 if Is_Access_Type (Etype (Fin_Mas_Id)) then
934 Append_To (Actuals, Fin_Mas_Act);
df3e68b1 935 else
d3f70b35
AC
936 Append_To (Actuals,
937 Make_Attribute_Reference (Loc,
938 Prefix => Fin_Mas_Act,
939 Attribute_Name => Name_Unrestricted_Access));
df3e68b1 940 end if;
d3f70b35
AC
941 else
942 Append_To (Actuals, Make_Null (Loc));
943 end if;
df3e68b1 944
d3f70b35 945 -- d) Finalize_Address
df3e68b1 946
60370fb1
AC
947 -- Primitive Finalize_Address is never generated in CodePeer mode
948 -- since it contains an Unchecked_Conversion.
df3e68b1 949
d1eb8a82 950 if Needs_Fin and then not CodePeer_Mode then
760804f3 951 Fin_Addr_Id := Finalize_Address (Desig_Typ);
ca5af305
AC
952 pragma Assert (Present (Fin_Addr_Id));
953
d3f70b35
AC
954 Append_To (Actuals,
955 Make_Attribute_Reference (Loc,
e4494292 956 Prefix => New_Occurrence_Of (Fin_Addr_Id, Loc),
d3f70b35
AC
957 Attribute_Name => Name_Unrestricted_Access));
958 else
959 Append_To (Actuals, Make_Null (Loc));
960 end if;
961 end if;
df3e68b1 962
d3f70b35
AC
963 -- e) Address
964 -- f) Storage_Size
965 -- g) Alignment
df3e68b1 966
e4494292
RD
967 Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc));
968 Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc));
6bed26b5 969
4c5e9870
SB
970 if (Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ))
971 and then not Use_Secondary_Stack_Pool
972 then
e4494292 973 Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc));
6bed26b5 974
f3296dd3 975 -- For deallocation of class-wide types we obtain the value of
6bed26b5
AC
976 -- alignment from the Type Specific Record of the deallocated object.
977 -- This is needed because the frontend expansion of class-wide types
bb072d1c 978 -- into equivalent types confuses the back end.
6bed26b5
AC
979
980 else
981 -- Generate:
982 -- Obj.all'Alignment
983
984 -- ... because 'Alignment applied to class-wide types is expanded
985 -- into the code that reads the value of alignment from the TSD
986 -- (see Expand_N_Attribute_Reference)
987
4c5e9870
SB
988 -- In the Use_Secondary_Stack_Pool case, Alig_Id is not
989 -- passed in and therefore must not be referenced.
990
6bed26b5
AC
991 Append_To (Actuals,
992 Unchecked_Convert_To (RTE (RE_Storage_Offset),
993 Make_Attribute_Reference (Loc,
033eaf85 994 Prefix =>
6bed26b5
AC
995 Make_Explicit_Dereference (Loc, Relocate_Node (Expr)),
996 Attribute_Name => Name_Alignment)));
997 end if;
df3e68b1 998
d3f70b35 999 -- h) Is_Controlled
df3e68b1 1000
d1eb8a82
AC
1001 if Needs_Fin then
1002 Is_Controlled : declare
31d922e3
AC
1003 Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F');
1004 Flag_Expr : Node_Id;
1005 Param : Node_Id;
3e720c96 1006 Pref : Node_Id;
31d922e3
AC
1007 Temp : Node_Id;
1008
1009 begin
1010 if Is_Allocate then
1011 Temp := Find_Object (Expression (Expr));
1012 else
1013 Temp := Expr;
1014 end if;
df3e68b1 1015
31d922e3
AC
1016 -- Processing for allocations where the expression is a subtype
1017 -- indication.
df3e68b1 1018
31d922e3
AC
1019 if Is_Allocate
1020 and then Is_Entity_Name (Temp)
1021 and then Is_Type (Entity (Temp))
1022 then
1023 Flag_Expr :=
e4494292 1024 New_Occurrence_Of
f3920a13
AC
1025 (Boolean_Literals
1026 (Needs_Finalization (Entity (Temp))), Loc);
df3e68b1 1027
31d922e3
AC
1028 -- The allocation / deallocation of a class-wide object relies
1029 -- on a runtime check to determine whether the object is truly
1030 -- controlled or not. Depending on this check, the finalization
1031 -- machinery will request or reclaim extra storage reserved for
1032 -- a list header.
df3e68b1 1033
31d922e3 1034 elsif Is_Class_Wide_Type (Desig_Typ) then
df3e68b1 1035
31d922e3
AC
1036 -- Detect a special case where interface class-wide types
1037 -- are involved as the object appears as:
f3920a13 1038
31d922e3 1039 -- Tag_Ptr (Base_Address (<object>'Address))
f3920a13 1040
31d922e3 1041 -- The expression already yields the proper tag, generate:
f3920a13 1042
31d922e3
AC
1043 -- Temp.all
1044
1045 if Is_RTE (Etype (Temp), RE_Tag_Ptr) then
1046 Param :=
1047 Make_Explicit_Dereference (Loc,
1048 Prefix => Relocate_Node (Temp));
1049
1050 -- In the default case, obtain the tag of the object about
1051 -- to be allocated / deallocated. Generate:
f3920a13 1052
31d922e3 1053 -- Temp'Tag
df3e68b1 1054
f8159014
AC
1055 -- If the object is an unchecked conversion (typically to
1056 -- an access to class-wide type), we must preserve the
1057 -- conversion to ensure that the object is seen as tagged
1058 -- in the code that follows.
1059
d3f70b35 1060 else
3e720c96
HK
1061 Pref := Temp;
1062
1063 if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion
f8159014 1064 then
3e720c96 1065 Pref := Parent (Pref);
f8159014 1066 end if;
3e720c96
HK
1067
1068 Param :=
1069 Make_Attribute_Reference (Loc,
1070 Prefix => Relocate_Node (Pref),
1071 Attribute_Name => Name_Tag);
d3f70b35
AC
1072 end if;
1073
31d922e3
AC
1074 -- Generate:
1075 -- Needs_Finalization (<Param>)
d3f70b35 1076
31d922e3
AC
1077 Flag_Expr :=
1078 Make_Function_Call (Loc,
1079 Name =>
e4494292 1080 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc),
31d922e3 1081 Parameter_Associations => New_List (Param));
d3f70b35 1082
31d922e3 1083 -- Processing for generic actuals
d3f70b35 1084
31d922e3
AC
1085 elsif Is_Generic_Actual_Type (Desig_Typ) then
1086 Flag_Expr :=
e4494292 1087 New_Occurrence_Of (Boolean_Literals
31d922e3 1088 (Needs_Finalization (Base_Type (Desig_Typ))), Loc);
ca5af305 1089
31d922e3
AC
1090 -- The object does not require any specialized checks, it is
1091 -- known to be controlled.
ca5af305 1092
31d922e3 1093 else
e4494292 1094 Flag_Expr := New_Occurrence_Of (Standard_True, Loc);
31d922e3
AC
1095 end if;
1096
1097 -- Create the temporary which represents the finalization state
1098 -- of the expression. Generate:
1099 --
1100 -- F : constant Boolean := <Flag_Expr>;
1101
1102 Insert_Action (N,
1103 Make_Object_Declaration (Loc,
1104 Defining_Identifier => Flag_Id,
1105 Constant_Present => True,
1106 Object_Definition =>
e4494292 1107 New_Occurrence_Of (Standard_Boolean, Loc),
31d922e3
AC
1108 Expression => Flag_Expr));
1109
e4494292 1110 Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc));
d1eb8a82 1111 end Is_Controlled;
31d922e3
AC
1112
1113 -- The object is not controlled
033eaf85 1114
d3f70b35 1115 else
e4494292 1116 Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc));
df3e68b1
HK
1117 end if;
1118
ca5af305
AC
1119 -- i) On_Subpool
1120
1121 if Is_Allocate then
1122 Append_To (Actuals,
e4494292 1123 New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc));
ca5af305
AC
1124 end if;
1125
d3f70b35
AC
1126 -- Step 2: Build a wrapper Allocate / Deallocate which internally
1127 -- calls Allocate_Any_Controlled / Deallocate_Any_Controlled.
1128
df3e68b1
HK
1129 -- Select the proper routine to call
1130
1131 if Is_Allocate then
d3f70b35 1132 Proc_To_Call := RTE (RE_Allocate_Any_Controlled);
df3e68b1 1133 else
d3f70b35 1134 Proc_To_Call := RTE (RE_Deallocate_Any_Controlled);
df3e68b1
HK
1135 end if;
1136
1137 -- Create a custom Allocate / Deallocate routine which has identical
1138 -- profile to that of System.Storage_Pools.
1139
4c5e9870
SB
1140 declare
1141 -- P : Root_Storage_Pool
1142 function Pool_Param return Node_Id is (
1143 Make_Parameter_Specification (Loc,
1144 Defining_Identifier => Make_Temporary (Loc, 'P'),
1145 Parameter_Type =>
1146 New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc)));
1147
1148 -- A : [out] Address
1149 function Address_Param return Node_Id is (
1150 Make_Parameter_Specification (Loc,
1151 Defining_Identifier => Addr_Id,
1152 Out_Present => Is_Allocate,
1153 Parameter_Type =>
1154 New_Occurrence_Of (RTE (RE_Address), Loc)));
1155
1156 -- S : Storage_Count
1157 function Size_Param return Node_Id is (
1158 Make_Parameter_Specification (Loc,
1159 Defining_Identifier => Size_Id,
1160 Parameter_Type =>
1161 New_Occurrence_Of (RTE (RE_Storage_Count), Loc)));
1162
1163 -- L : Storage_Count
1164 function Alignment_Param return Node_Id is (
1165 Make_Parameter_Specification (Loc,
1166 Defining_Identifier => Alig_Id,
1167 Parameter_Type =>
1168 New_Occurrence_Of (RTE (RE_Storage_Count), Loc)));
1169
1170 Formal_Params : List_Id;
1171 begin
1172 if Use_Secondary_Stack_Pool then
1173 -- Gigi expects a different profile in the Secondary_Stack_Pool
1174 -- case. There must be no uses of the two missing formals
1175 -- (i.e., Pool_Param and Alignment_Param) in this case.
1176 Formal_Params := New_List (Address_Param, Size_Param);
1177 else
1178 Formal_Params := New_List (
1179 Pool_Param, Address_Param, Size_Param, Alignment_Param);
1180 end if;
df3e68b1 1181
4c5e9870
SB
1182 Insert_Action (N,
1183 Make_Subprogram_Body (Loc,
1184 Specification =>
1185 -- procedure Pnn
1186 Make_Procedure_Specification (Loc,
1187 Defining_Unit_Name => Proc_Id,
1188 Parameter_Specifications => Formal_Params),
1189
1190 Declarations => No_List,
1191
1192 Handled_Statement_Sequence =>
1193 Make_Handled_Sequence_Of_Statements (Loc,
1194 Statements => New_List (
1195 Make_Procedure_Call_Statement (Loc,
1196 Name =>
1197 New_Occurrence_Of (Proc_To_Call, Loc),
1198 Parameter_Associations => Actuals)))),
1199 Suppress => All_Checks);
1200 end;
df3e68b1
HK
1201
1202 -- The newly generated Allocate / Deallocate becomes the default
1203 -- procedure to call when the back end processes the allocation /
1204 -- deallocation.
1205
1206 if Is_Allocate then
1207 Set_Procedure_To_Call (Expr, Proc_Id);
1208 else
1209 Set_Procedure_To_Call (N, Proc_Id);
1210 end if;
1211 end;
1212 end Build_Allocate_Deallocate_Proc;
1213
bb072d1c
AC
1214 -------------------------------
1215 -- Build_Abort_Undefer_Block --
1216 -------------------------------
1217
1218 function Build_Abort_Undefer_Block
1219 (Loc : Source_Ptr;
1220 Stmts : List_Id;
1221 Context : Node_Id) return Node_Id
1222 is
1223 Exceptions_OK : constant Boolean :=
1224 not Restriction_Active (No_Exception_Propagation);
1225
1226 AUD : Entity_Id;
1227 Blk : Node_Id;
1228 Blk_Id : Entity_Id;
1229 HSS : Node_Id;
1230
1231 begin
1232 -- The block should be generated only when undeferring abort in the
1233 -- context of a potential exception.
1234
1235 pragma Assert (Abort_Allowed and Exceptions_OK);
1236
1237 -- Generate:
1238 -- begin
1239 -- <Stmts>
1240 -- at end
1241 -- Abort_Undefer_Direct;
1242 -- end;
1243
1244 AUD := RTE (RE_Abort_Undefer_Direct);
1245
1246 HSS :=
1247 Make_Handled_Sequence_Of_Statements (Loc,
1248 Statements => Stmts,
1249 At_End_Proc => New_Occurrence_Of (AUD, Loc));
1250
1251 Blk :=
1252 Make_Block_Statement (Loc,
1253 Handled_Statement_Sequence => HSS);
1254 Set_Is_Abort_Block (Blk);
1255
1256 Add_Block_Identifier (Blk, Blk_Id);
1257 Expand_At_End_Handler (HSS, Blk_Id);
1258
1259 -- Present the Abort_Undefer_Direct function to the back end to inline
1260 -- the call to the routine.
1261
1262 Add_Inlined_Body (AUD, Context);
1263
1264 return Blk;
1265 end Build_Abort_Undefer_Block;
1266
f63d601b
HK
1267 ---------------------------------
1268 -- Build_Class_Wide_Expression --
1269 ---------------------------------
1270
1271 procedure Build_Class_Wide_Expression
a187206c
AC
1272 (Prag : Node_Id;
1273 Subp : Entity_Id;
1274 Par_Subp : Entity_Id;
1275 Adjust_Sloc : Boolean;
1276 Needs_Wrapper : out Boolean)
f63d601b
HK
1277 is
1278 function Replace_Entity (N : Node_Id) return Traverse_Result;
1279 -- Replace reference to formal of inherited operation or to primitive
1280 -- operation of root type, with corresponding entity for derived type,
1281 -- when constructing the class-wide condition of an overriding
1282 -- subprogram.
1283
1284 --------------------
1285 -- Replace_Entity --
1286 --------------------
1287
1288 function Replace_Entity (N : Node_Id) return Traverse_Result is
1289 New_E : Entity_Id;
1290
1291 begin
1292 if Adjust_Sloc then
1293 Adjust_Inherited_Pragma_Sloc (N);
1294 end if;
1295
1296 if Nkind (N) = N_Identifier
1297 and then Present (Entity (N))
1298 and then
1299 (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
1300 and then
1301 (Nkind (Parent (N)) /= N_Attribute_Reference
1302 or else Attribute_Name (Parent (N)) /= Name_Class)
1303 then
1304 -- The replacement does not apply to dispatching calls within the
1305 -- condition, but only to calls whose static tag is that of the
1306 -- parent type.
1307
1308 if Is_Subprogram (Entity (N))
1309 and then Nkind (Parent (N)) = N_Function_Call
1310 and then Present (Controlling_Argument (Parent (N)))
1311 then
1312 return OK;
1313 end if;
1314
1315 -- Determine whether entity has a renaming
1316
b619c88e 1317 New_E := Type_Map.Get (Entity (N));
f63d601b
HK
1318
1319 if Present (New_E) then
1320 Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
a187206c 1321
10fdda1c
HK
1322 -- AI12-0166: a precondition for a protected operation
1323 -- cannot include an internal call to a protected function
1324 -- of the type. In the case of an inherited condition for an
1325 -- overriding operation, both the operation and the function
1326 -- are given by primitive wrappers.
2d6f6e08 1327 -- Move this check to sem???
5cb78fb8
ES
1328
1329 if Ekind (New_E) = E_Function
1330 and then Is_Primitive_Wrapper (New_E)
1331 and then Is_Primitive_Wrapper (Subp)
1332 and then Scope (Subp) = Scope (New_E)
9f0d76ec 1333 and then Chars (Pragma_Identifier (Prag)) = Name_Precondition
5cb78fb8
ES
1334 then
1335 Error_Msg_Node_2 := Wrapped_Entity (Subp);
1336 Error_Msg_NE
1337 ("internal call to& cannot appear in inherited "
1338 & "precondition of protected operation&",
10fdda1c 1339 N, Wrapped_Entity (New_E));
5cb78fb8
ES
1340 end if;
1341
ef952fd5
HK
1342 -- If the entity is an overridden primitive and we are not
1343 -- in GNATprove mode, we must build a wrapper for the current
8ab31c0c
AC
1344 -- inherited operation. If the reference is the prefix of an
1345 -- attribute such as 'Result (or others ???) there is no need
e6326de5 1346 -- for a wrapper: the condition is just rewritten in terms of
8ab31c0c
AC
1347 -- the inherited subprogram.
1348
1349 if Is_Subprogram (New_E)
1350 and then Nkind (Parent (N)) /= N_Attribute_Reference
ef952fd5 1351 and then not GNATprove_Mode
8ab31c0c 1352 then
a187206c
AC
1353 Needs_Wrapper := True;
1354 end if;
f63d601b
HK
1355 end if;
1356
1357 -- Check that there are no calls left to abstract operations if
1358 -- the current subprogram is not abstract.
2d6f6e08 1359 -- Move this check to sem???
f63d601b
HK
1360
1361 if Nkind (Parent (N)) = N_Function_Call
1362 and then N = Name (Parent (N))
1363 then
1364 if not Is_Abstract_Subprogram (Subp)
1365 and then Is_Abstract_Subprogram (Entity (N))
1366 then
3b2249aa 1367 Error_Msg_Sloc := Sloc (Current_Scope);
6dd86c75
AC
1368 Error_Msg_Node_2 := Subp;
1369 if Comes_From_Source (Subp) then
1370 Error_Msg_NE
3b2249aa
HK
1371 ("cannot call abstract subprogram & in inherited "
1372 & "condition for&#", Subp, Entity (N));
6dd86c75
AC
1373 else
1374 Error_Msg_NE
3b2249aa
HK
1375 ("cannot call abstract subprogram & in inherited "
1376 & "condition for inherited&#", Subp, Entity (N));
6dd86c75 1377 end if;
f63d601b
HK
1378
1379 -- In SPARK mode, reject an inherited condition for an
1380 -- inherited operation if it contains a call to an overriding
e51102b2 1381 -- operation, because this implies that the pre/postconditions
f63d601b
HK
1382 -- of the inherited operation have changed silently.
1383
1384 elsif SPARK_Mode = On
1385 and then Warn_On_Suspicious_Contract
1386 and then Present (Alias (Subp))
1387 and then Present (New_E)
1388 and then Comes_From_Source (New_E)
1389 then
1390 Error_Msg_N
1391 ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
1392 Parent (Subp));
1393 Error_Msg_Sloc := Sloc (New_E);
1394 Error_Msg_Node_2 := Subp;
1395 Error_Msg_NE
1396 ("\overriding of&# forces overriding of&",
1397 Parent (Subp), New_E);
1398 end if;
1399 end if;
1400
1401 -- Update type of function call node, which should be the same as
1402 -- the function's return type.
1403
1404 if Is_Subprogram (Entity (N))
1405 and then Nkind (Parent (N)) = N_Function_Call
1406 then
1407 Set_Etype (Parent (N), Etype (Entity (N)));
1408 end if;
1409
1410 -- The whole expression will be reanalyzed
1411
1412 elsif Nkind (N) in N_Has_Etype then
1413 Set_Analyzed (N, False);
1414 end if;
1415
1416 return OK;
1417 end Replace_Entity;
1418
1419 procedure Replace_Condition_Entities is
1420 new Traverse_Proc (Replace_Entity);
1421
1422 -- Local variables
1423
1424 Par_Formal : Entity_Id;
1425 Subp_Formal : Entity_Id;
1426
1427 -- Start of processing for Build_Class_Wide_Expression
1428
1429 begin
a187206c
AC
1430 Needs_Wrapper := False;
1431
f63d601b
HK
1432 -- Add mapping from old formals to new formals
1433
1434 Par_Formal := First_Formal (Par_Subp);
1435 Subp_Formal := First_Formal (Subp);
1436
1437 while Present (Par_Formal) and then Present (Subp_Formal) loop
b619c88e 1438 Type_Map.Set (Par_Formal, Subp_Formal);
f63d601b
HK
1439 Next_Formal (Par_Formal);
1440 Next_Formal (Subp_Formal);
1441 end loop;
1442
1443 Replace_Condition_Entities (Prag);
1444 end Build_Class_Wide_Expression;
1445
1446 --------------------
1447 -- Build_DIC_Call --
1448 --------------------
1449
1450 function Build_DIC_Call
f7937111
GD
1451 (Loc : Source_Ptr;
1452 Obj_Name : Node_Id;
1453 Typ : Entity_Id) return Node_Id
f63d601b
HK
1454 is
1455 Proc_Id : constant Entity_Id := DIC_Procedure (Typ);
1456 Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id));
1457
1458 begin
f7937111
GD
1459 -- The DIC procedure has a null body if assertions are disabled or
1460 -- Assertion_Policy Ignore is in effect. In that case, it would be
1461 -- nice to generate a null statement instead of a call to the DIC
1462 -- procedure, but doing that seems to interfere with the determination
1463 -- of ECRs (early call regions) in SPARK. ???
1464
f63d601b
HK
1465 return
1466 Make_Procedure_Call_Statement (Loc,
1467 Name => New_Occurrence_Of (Proc_Id, Loc),
1468 Parameter_Associations => New_List (
1469 Make_Unchecked_Type_Conversion (Loc,
1470 Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc),
f7937111 1471 Expression => Obj_Name)));
f63d601b
HK
1472 end Build_DIC_Call;
1473
1474 ------------------------------
1475 -- Build_DIC_Procedure_Body --
1476 ------------------------------
1477
b0bf18ad
AC
1478 -- WARNING: This routine manages Ghost regions. Return statements must be
1479 -- replaced by gotos which jump to the end of the routine and restore the
1480 -- Ghost mode.
1481
b619c88e 1482 procedure Build_DIC_Procedure_Body
f7937111
GD
1483 (Typ : Entity_Id;
1484 Partial_DIC : Boolean := False)
b619c88e 1485 is
f7937111
GD
1486 Pragmas_Seen : Elist_Id := No_Elist;
1487 -- This list contains all DIC pragmas processed so far. The list is used
1488 -- to avoid redundant Default_Initial_Condition checks.
1489
f63d601b
HK
1490 procedure Add_DIC_Check
1491 (DIC_Prag : Node_Id;
1492 DIC_Expr : Node_Id;
1493 Stmts : in out List_Id);
1494 -- Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify
1495 -- assertion expression DIC_Expr of pragma DIC_Prag. All generated code
1496 -- is added to list Stmts.
1497
1498 procedure Add_Inherited_DIC
1499 (DIC_Prag : Node_Id;
1500 Par_Typ : Entity_Id;
1501 Deriv_Typ : Entity_Id;
1502 Stmts : in out List_Id);
1503 -- Add a runtime check to verify the assertion expression of inherited
e51102b2 1504 -- pragma DIC_Prag. Par_Typ is parent type, which is also the owner of
f63d601b
HK
1505 -- the DIC pragma. Deriv_Typ is the derived type inheriting the DIC
1506 -- pragma. All generated code is added to list Stmts.
1507
1508 procedure Add_Inherited_Tagged_DIC
f7937111
GD
1509 (DIC_Prag : Node_Id;
1510 Expr : Node_Id;
1511 Stmts : in out List_Id);
f63d601b 1512 -- Add a runtime check to verify assertion expression DIC_Expr of
f7937111
GD
1513 -- inherited pragma DIC_Prag. This routine applies class-wide pre-
1514 -- and postcondition-like runtime semantics to the check. Expr is
1515 -- the assertion expression after substitition has been performed
1516 -- (via Replace_References). All generated code is added to list Stmts.
1517
1518 procedure Add_Inherited_DICs
1519 (T : Entity_Id;
1520 Priv_Typ : Entity_Id;
1521 Full_Typ : Entity_Id;
1522 Obj_Id : Entity_Id;
1523 Checks : in out List_Id);
1524 -- Generate a DIC check for each inherited Default_Initial_Condition
1525 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote
1526 -- the partial and full view of the parent type. Obj_Id denotes the
1527 -- entity of the _object formal parameter of the DIC procedure. All
1528 -- created checks are added to list Checks.
f63d601b
HK
1529
1530 procedure Add_Own_DIC
1531 (DIC_Prag : Node_Id;
1532 DIC_Typ : Entity_Id;
f7937111 1533 Obj_Id : Entity_Id;
f63d601b
HK
1534 Stmts : in out List_Id);
1535 -- Add a runtime check to verify the assertion expression of pragma
f7937111
GD
1536 -- DIC_Prag. DIC_Typ is the owner of the DIC pragma. Obj_Id is the
1537 -- object to substitute in the assertion expression for any references
1538 -- to the current instance of the type All generated code is added to
1539 -- list Stmts.
1540
1541 procedure Add_Parent_DICs
1542 (T : Entity_Id;
1543 Obj_Id : Entity_Id;
1544 Checks : in out List_Id);
1545 -- Generate a Default_Initial_Condition check for each inherited DIC
1546 -- aspect coming from all parent types of type T. Obj_Id denotes the
1547 -- entity of the _object formal parameter of the DIC procedure. All
1548 -- created checks are added to list Checks.
f63d601b 1549
f63d601b
HK
1550 -------------------
1551 -- Add_DIC_Check --
1552 -------------------
1553
1554 procedure Add_DIC_Check
1555 (DIC_Prag : Node_Id;
1556 DIC_Expr : Node_Id;
1557 Stmts : in out List_Id)
1558 is
1559 Loc : constant Source_Ptr := Sloc (DIC_Prag);
1560 Nam : constant Name_Id := Original_Aspect_Pragma_Name (DIC_Prag);
1561
1562 begin
1563 -- The DIC pragma is ignored, nothing left to do
1564
1565 if Is_Ignored (DIC_Prag) then
1566 null;
1567
ca0b6141
AC
1568 -- Otherwise the DIC expression must be checked at run time.
1569 -- Generate:
f63d601b
HK
1570
1571 -- pragma Check (<Nam>, <DIC_Expr>);
1572
1573 else
1574 Append_New_To (Stmts,
1575 Make_Pragma (Loc,
1576 Pragma_Identifier =>
1577 Make_Identifier (Loc, Name_Check),
1578
1579 Pragma_Argument_Associations => New_List (
1580 Make_Pragma_Argument_Association (Loc,
1581 Expression => Make_Identifier (Loc, Nam)),
1582
1583 Make_Pragma_Argument_Association (Loc,
1584 Expression => DIC_Expr))));
1585 end if;
f7937111
GD
1586
1587 -- Add the pragma to the list of processed pragmas
1588
1589 Append_New_Elmt (DIC_Prag, Pragmas_Seen);
f63d601b
HK
1590 end Add_DIC_Check;
1591
1592 -----------------------
1593 -- Add_Inherited_DIC --
1594 -----------------------
1595
1596 procedure Add_Inherited_DIC
1597 (DIC_Prag : Node_Id;
1598 Par_Typ : Entity_Id;
1599 Deriv_Typ : Entity_Id;
1600 Stmts : in out List_Id)
1601 is
1602 Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ);
1603 Deriv_Obj : constant Entity_Id := First_Entity (Deriv_Proc);
1604 Par_Proc : constant Entity_Id := DIC_Procedure (Par_Typ);
1605 Par_Obj : constant Entity_Id := First_Entity (Par_Proc);
1606 Loc : constant Source_Ptr := Sloc (DIC_Prag);
1607
1608 begin
1609 pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc));
1610
1611 -- Verify the inherited DIC assertion expression by calling the DIC
1612 -- procedure of the parent type.
1613
1614 -- Generate:
1615 -- <Par_Typ>DIC (Par_Typ (_object));
1616
1617 Append_New_To (Stmts,
1618 Make_Procedure_Call_Statement (Loc,
1619 Name => New_Occurrence_Of (Par_Proc, Loc),
1620 Parameter_Associations => New_List (
1621 Convert_To
1622 (Typ => Etype (Par_Obj),
1623 Expr => New_Occurrence_Of (Deriv_Obj, Loc)))));
1624 end Add_Inherited_DIC;
1625
1626 ------------------------------
1627 -- Add_Inherited_Tagged_DIC --
1628 ------------------------------
1629
1630 procedure Add_Inherited_Tagged_DIC
f7937111
GD
1631 (DIC_Prag : Node_Id;
1632 Expr : Node_Id;
1633 Stmts : in out List_Id)
f63d601b 1634 is
f7937111
GD
1635 begin
1636 -- Once the DIC assertion expression is fully processed, add a check
1637 -- to the statements of the DIC procedure.
f63d601b 1638
f7937111
GD
1639 Add_DIC_Check
1640 (DIC_Prag => DIC_Prag,
1641 DIC_Expr => Expr,
1642 Stmts => Stmts);
1643 end Add_Inherited_Tagged_DIC;
1644
1645 ------------------------
1646 -- Add_Inherited_DICs --
1647 ------------------------
1648
1649 procedure Add_Inherited_DICs
1650 (T : Entity_Id;
1651 Priv_Typ : Entity_Id;
1652 Full_Typ : Entity_Id;
1653 Obj_Id : Entity_Id;
1654 Checks : in out List_Id)
1655 is
1656 Deriv_Typ : Entity_Id;
1657 Expr : Node_Id;
1658 Prag : Node_Id;
1659 Prag_Expr : Node_Id;
1660 Prag_Expr_Arg : Node_Id;
1661 Prag_Typ : Node_Id;
1662 Prag_Typ_Arg : Node_Id;
1663
1664 Par_Proc : Entity_Id;
1665 -- The "partial" invariant procedure of Par_Typ
1666
1667 Par_Typ : Entity_Id;
1668 -- The suitable view of the parent type used in the substitution of
1669 -- type attributes.
f63d601b
HK
1670
1671 begin
f7937111
GD
1672 if not Present (Priv_Typ) and then not Present (Full_Typ) then
1673 return;
1674 end if;
f63d601b 1675
f7937111
GD
1676 -- When the type inheriting the class-wide invariant is a concurrent
1677 -- type, use the corresponding record type because it contains all
1678 -- primitive operations of the concurrent type and allows for proper
1679 -- substitution.
f63d601b 1680
f7937111
GD
1681 if Is_Concurrent_Type (T) then
1682 Deriv_Typ := Corresponding_Record_Type (T);
1683 else
1684 Deriv_Typ := T;
1685 end if;
f63d601b 1686
f7937111 1687 pragma Assert (Present (Deriv_Typ));
f63d601b 1688
f7937111
GD
1689 -- Determine which rep item chain to use. Precedence is given to that
1690 -- of the parent type's partial view since it usually carries all the
1691 -- class-wide invariants.
b619c88e 1692
f7937111
GD
1693 if Present (Priv_Typ) then
1694 Prag := First_Rep_Item (Priv_Typ);
1695 else
1696 Prag := First_Rep_Item (Full_Typ);
1697 end if;
f63d601b 1698
f7937111
GD
1699 while Present (Prag) loop
1700 if Nkind (Prag) = N_Pragma
1701 and then Pragma_Name (Prag) = Name_Default_Initial_Condition
1702 then
1703 -- Nothing to do if the pragma was already processed
f63d601b 1704
f7937111
GD
1705 if Contains (Pragmas_Seen, Prag) then
1706 return;
1707 end if;
f63d601b 1708
f7937111 1709 -- Extract arguments of the Default_Initial_Condition pragma
27bb7941 1710
f7937111
GD
1711 Prag_Expr_Arg := First (Pragma_Argument_Associations (Prag));
1712 Prag_Expr := Expression_Copy (Prag_Expr_Arg);
f63d601b 1713
f7937111
GD
1714 -- Pick up the implicit second argument of the pragma, which
1715 -- indicates the type that the pragma applies to.
f63d601b 1716
f7937111
GD
1717 Prag_Typ_Arg := Next (Prag_Expr_Arg);
1718 if Present (Prag_Typ_Arg) then
1719 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
1720 else
1721 Prag_Typ := Empty;
1722 end if;
1723
1724 -- The pragma applies to the partial view of the parent type
1725
1726 if Present (Priv_Typ)
1727 and then Present (Prag_Typ)
1728 and then Entity (Prag_Typ) = Priv_Typ
1729 then
1730 Par_Typ := Priv_Typ;
1731
1732 -- The pragma applies to the full view of the parent type
1733
1734 elsif Present (Full_Typ)
1735 and then Present (Prag_Typ)
1736 and then Entity (Prag_Typ) = Full_Typ
1737 then
1738 Par_Typ := Full_Typ;
1739
1740 -- Otherwise the pragma does not belong to the parent type and
1741 -- should not be considered.
1742
1743 else
1744 return;
1745 end if;
1746
1747 -- Substitute references in the DIC expression that are related
1748 -- to the partial type with corresponding references related to
1749 -- the derived type (call to Replace_References below).
1750
1751 Expr := New_Copy_Tree (Prag_Expr);
1752
1753 Par_Proc := Partial_DIC_Procedure (Par_Typ);
1754
1755 -- If there's not a partial DIC procedure (such as when a
1756 -- full type doesn't have its own DIC, but is inherited from
1757 -- a type with DIC), get the full DIC procedure.
1758
1759 if not Present (Par_Proc) then
1760 Par_Proc := DIC_Procedure (Par_Typ);
1761 end if;
1762
1763 Replace_References
1764 (Expr => Expr,
1765 Par_Typ => Par_Typ,
1766 Deriv_Typ => Deriv_Typ,
1767 Par_Obj => First_Formal (Par_Proc),
1768 Deriv_Obj => Obj_Id);
1769
1770 -- Why are there different actions depending on whether T is
1771 -- tagged? Can these be unified? ???
1772
1773 if Is_Tagged_Type (T) then
1774 Add_Inherited_Tagged_DIC
1775 (DIC_Prag => Prag,
1776 Expr => Expr,
1777 Stmts => Checks);
1778
1779 else
1780 Add_Inherited_DIC
1781 (DIC_Prag => Prag,
1782 Par_Typ => Par_Typ,
1783 Deriv_Typ => Deriv_Typ,
1784 Stmts => Checks);
1785 end if;
1786
1787 -- Leave as soon as we get a DIC pragma, since we'll visit
1788 -- the pragmas of the parents, so will get to any "inherited"
1789 -- pragmas that way.
1790
1791 return;
1792 end if;
1793
1794 Next_Rep_Item (Prag);
1795 end loop;
1796 end Add_Inherited_DICs;
f63d601b
HK
1797
1798 -----------------
1799 -- Add_Own_DIC --
1800 -----------------
1801
1802 procedure Add_Own_DIC
1803 (DIC_Prag : Node_Id;
1804 DIC_Typ : Entity_Id;
f7937111 1805 Obj_Id : Entity_Id;
f63d601b
HK
1806 Stmts : in out List_Id)
1807 is
1808 DIC_Args : constant List_Id :=
1809 Pragma_Argument_Associations (DIC_Prag);
1810 DIC_Arg : constant Node_Id := First (DIC_Args);
1811 DIC_Asp : constant Node_Id := Corresponding_Aspect (DIC_Prag);
1812 DIC_Expr : constant Node_Id := Get_Pragma_Arg (DIC_Arg);
f63d601b 1813
f63d601b
HK
1814 -- Local variables
1815
1816 Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ);
1817
1818 Expr : Node_Id;
1819
1820 -- Start of processing for Add_Own_DIC
1821
1822 begin
b3801819 1823 pragma Assert (Present (DIC_Expr));
f63d601b
HK
1824 Expr := New_Copy_Tree (DIC_Expr);
1825
e51102b2 1826 -- Perform the following substitution:
f63d601b
HK
1827
1828 -- * Replace the current instance of DIC_Typ with a reference to
1829 -- the _object formal parameter of the DIC procedure.
1830
1831 Replace_Type_References
1832 (Expr => Expr,
1833 Typ => DIC_Typ,
1834 Obj_Id => Obj_Id);
1835
1836 -- Preanalyze the DIC expression to detect errors and at the same
1837 -- time capture the visibility of the proper package part.
1838
1839 Set_Parent (Expr, Typ_Decl);
1840 Preanalyze_Assert_Expression (Expr, Any_Boolean);
1841
1842 -- Save a copy of the expression with all replacements and analysis
1843 -- already taken place in case a derived type inherits the pragma.
1844 -- The copy will be used as the foundation of the derived type's own
1845 -- version of the DIC assertion expression.
1846
1847 if Is_Tagged_Type (DIC_Typ) then
1848 Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr));
1849 end if;
1850
1851 -- If the pragma comes from an aspect specification, replace the
1852 -- saved expression because all type references must be substituted
1853 -- for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx
1854 -- routines.
1855
1856 if Present (DIC_Asp) then
1857 Set_Entity (Identifier (DIC_Asp), New_Copy_Tree (Expr));
1858 end if;
1859
f63d601b 1860 -- Once the DIC assertion expression is fully processed, add a check
d2e59934
GD
1861 -- to the statements of the DIC procedure (unless the type is an
1862 -- abstract type, in which case we don't want the possibility of
1863 -- generating a call to an abstract function of the type; such DIC
1864 -- procedures can never be called in any case, so not generating the
1865 -- check at all is OK).
1866
427c07a2 1867 if not Is_Abstract_Type (DIC_Typ) or else GNATprove_Mode then
d2e59934
GD
1868 Add_DIC_Check
1869 (DIC_Prag => DIC_Prag,
1870 DIC_Expr => Expr,
1871 Stmts => Stmts);
1872 end if;
f63d601b
HK
1873 end Add_Own_DIC;
1874
f7937111
GD
1875 ---------------------
1876 -- Add_Parent_DICs --
1877 ---------------------
1878
1879 procedure Add_Parent_DICs
1880 (T : Entity_Id;
1881 Obj_Id : Entity_Id;
1882 Checks : in out List_Id)
1883 is
1884 Dummy_1 : Entity_Id;
1885 Dummy_2 : Entity_Id;
1886
1887 Curr_Typ : Entity_Id;
1888 -- The entity of the current type being examined
1889
1890 Full_Typ : Entity_Id;
1891 -- The full view of Par_Typ
1892
1893 Par_Typ : Entity_Id;
1894 -- The entity of the parent type
1895
1896 Priv_Typ : Entity_Id;
1897 -- The partial view of Par_Typ
1898
1899 begin
1900 -- Climb the parent type chain
1901
1902 Curr_Typ := T;
1903 loop
1904 -- Do not consider subtypes, as they inherit the DICs from their
1905 -- base types.
1906
1907 Par_Typ := Base_Type (Etype (Base_Type (Curr_Typ)));
1908
1909 -- Stop the climb once the root of the parent chain is
1910 -- reached.
1911
1912 exit when Curr_Typ = Par_Typ;
1913
1914 -- Process the DICs of the parent type
1915
1916 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
1917
1918 -- Only try to inherit a DIC pragma from the parent type Par_Typ
1919 -- if it Has_Own_DIC pragma. The loop will proceed up the parent
1920 -- chain to find all types that have their own DIC.
1921
1922 if Has_Own_DIC (Par_Typ) then
1923 Add_Inherited_DICs
1924 (T => T,
1925 Priv_Typ => Priv_Typ,
1926 Full_Typ => Full_Typ,
1927 Obj_Id => Obj_Id,
1928 Checks => Checks);
1929 end if;
1930
1931 Curr_Typ := Par_Typ;
1932 end loop;
1933 end Add_Parent_DICs;
1934
f63d601b
HK
1935 -- Local variables
1936
1937 Loc : constant Source_Ptr := Sloc (Typ);
1938
9057bd6a
HK
1939 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
1940 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
1941 -- Save the Ghost-related attributes to restore on exit
f9a8f910 1942
f63d601b
HK
1943 DIC_Prag : Node_Id;
1944 DIC_Typ : Entity_Id;
1945 Dummy_1 : Entity_Id;
1946 Dummy_2 : Entity_Id;
1947 Proc_Body : Node_Id;
1948 Proc_Body_Id : Entity_Id;
1949 Proc_Decl : Node_Id;
1950 Proc_Id : Entity_Id;
1951 Stmts : List_Id := No_List;
1952
f7937111
GD
1953 CRec_Typ : Entity_Id := Empty;
1954 -- The corresponding record type of Full_Typ
1955
1956 Full_Typ : Entity_Id := Empty;
1957 -- The full view of the working type
1958
1959 Obj_Id : Entity_Id := Empty;
1960 -- The _object formal parameter of the invariant procedure
1961
1962 Part_Proc : Entity_Id := Empty;
1963 -- The entity of the "partial" invariant procedure
1964
1965 Priv_Typ : Entity_Id := Empty;
1966 -- The partial view of the working type
b619c88e 1967
f63d601b
HK
1968 Work_Typ : Entity_Id;
1969 -- The working type
1970
1971 -- Start of processing for Build_DIC_Procedure_Body
1972
1973 begin
ce06d641 1974 Work_Typ := Base_Type (Typ);
f63d601b 1975
ce06d641
AC
1976 -- Do not process class-wide types as these are Itypes, but lack a first
1977 -- subtype (see below).
f63d601b 1978
ce06d641
AC
1979 if Is_Class_Wide_Type (Work_Typ) then
1980 return;
1981
1982 -- Do not process the underlying full view of a private type. There is
1983 -- no way to get back to the partial view, plus the body will be built
1984 -- by the full view or the base type.
1985
1986 elsif Is_Underlying_Full_View (Work_Typ) then
1987 return;
1988
1989 -- Use the first subtype when dealing with various base types
1990
1991 elsif Is_Itype (Work_Typ) then
f63d601b
HK
1992 Work_Typ := First_Subtype (Work_Typ);
1993
1994 -- The input denotes the corresponding record type of a protected or a
1995 -- task type. Work with the concurrent type because the corresponding
1996 -- record type may not be visible to clients of the type.
1997
1998 elsif Ekind (Work_Typ) = E_Record_Type
1999 and then Is_Concurrent_Record_Type (Work_Typ)
2000 then
2001 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
2002 end if;
2003
d65a80fd
HK
2004 -- The working type may be subject to pragma Ghost. Set the mode now to
2005 -- ensure that the DIC procedure is properly marked as Ghost.
2006
f9a8f910 2007 Set_Ghost_Mode (Work_Typ);
d65a80fd 2008
f63d601b
HK
2009 -- The working type must be either define a DIC pragma of its own or
2010 -- inherit one from a parent type.
2011
2012 pragma Assert (Has_DIC (Work_Typ));
2013
2014 -- Recover the type which defines the DIC pragma. This is either the
2015 -- working type itself or a parent type when the pragma is inherited.
2016
2017 DIC_Typ := Find_DIC_Type (Work_Typ);
2018 pragma Assert (Present (DIC_Typ));
2019
2020 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2021 pragma Assert (Present (DIC_Prag));
2022
2023 -- Nothing to do if pragma DIC appears without an argument or its sole
2024 -- argument is "null".
2025
2026 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
d65a80fd 2027 goto Leave;
f63d601b
HK
2028 end if;
2029
f7937111
GD
2030 -- Obtain both views of the type
2031
2032 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy_1, CRec_Typ);
f63d601b 2033
f7937111 2034 -- The caller requests a body for the partial DIC procedure
f63d601b 2035
f7937111
GD
2036 if Partial_DIC then
2037 Proc_Id := Partial_DIC_Procedure (Work_Typ);
f63d601b 2038
f7937111 2039 -- The "full" DIC procedure body was already created
f63d601b 2040
f7937111
GD
2041 -- Create a declaration for the "partial" DIC procedure if it
2042 -- is not available.
2043
2044 if No (Proc_Id) then
2045 Build_DIC_Procedure_Declaration
2046 (Typ => Work_Typ,
2047 Partial_DIC => True);
f63d601b 2048
f7937111
GD
2049 Proc_Id := Partial_DIC_Procedure (Work_Typ);
2050 end if;
2051
2052 -- The caller requests a body for the "full" DIC procedure
2053
2054 else
2055 Proc_Id := DIC_Procedure (Work_Typ);
2056 Part_Proc := Partial_DIC_Procedure (Work_Typ);
2057
2058 -- Create a declaration for the "full" DIC procedure if it is
2059 -- not available.
2060
2061 if No (Proc_Id) then
2062 Build_DIC_Procedure_Declaration (Work_Typ);
2063 Proc_Id := DIC_Procedure (Work_Typ);
2064 end if;
f63d601b
HK
2065 end if;
2066
2067 -- At this point there should be a DIC procedure declaration
2068
2069 pragma Assert (Present (Proc_Id));
2070 Proc_Decl := Unit_Declaration_Node (Proc_Id);
2071
2072 -- Nothing to do if the DIC procedure already has a body
2073
2074 if Present (Corresponding_Body (Proc_Decl)) then
d65a80fd 2075 goto Leave;
f63d601b
HK
2076 end if;
2077
f63d601b
HK
2078 -- Emulate the environment of the DIC procedure by installing its scope
2079 -- and formal parameters.
2080
2081 Push_Scope (Proc_Id);
2082 Install_Formals (Proc_Id);
2083
f7937111
GD
2084 Obj_Id := First_Formal (Proc_Id);
2085 pragma Assert (Present (Obj_Id));
f63d601b 2086
f7937111
GD
2087 -- The "partial" DIC procedure verifies the DICs of the partial view
2088 -- only.
f63d601b 2089
f7937111
GD
2090 if Partial_DIC then
2091 pragma Assert (Present (Priv_Typ));
2092
2093 if Has_Own_DIC (Work_Typ) then -- If we're testing this then maybe
2094 Add_Own_DIC -- we shouldn't be calling Find_DIC_Typ above???
2095 (DIC_Prag => DIC_Prag,
2096 DIC_Typ => DIC_Typ, -- Should this just be Work_Typ???
2097 Obj_Id => Obj_Id,
2098 Stmts => Stmts);
2099 end if;
f63d601b 2100
f7937111
GD
2101 -- Otherwise the "full" DIC procedure verifies the DICs of the full
2102 -- view, well as DICs inherited from parent types. In addition, it
2103 -- indirectly verifies the DICs of the partial view by calling the
2104 -- "partial" DIC procedure.
f63d601b 2105
f7937111
GD
2106 else
2107 pragma Assert (Present (Full_Typ));
b619c88e 2108
f7937111
GD
2109 -- Check the DIC of the partial view by calling the "partial" DIC
2110 -- procedure, unless the partial DIC body is empty. Generate:
f63d601b 2111
f7937111
GD
2112 -- <Work_Typ>Partial_DIC (_object);
2113
2114 if Present (Part_Proc) and then not Has_Null_Body (Part_Proc) then
2115 Append_New_To (Stmts,
2116 Make_Procedure_Call_Statement (Loc,
2117 Name => New_Occurrence_Of (Part_Proc, Loc),
2118 Parameter_Associations => New_List (
2119 New_Occurrence_Of (Obj_Id, Loc))));
2120 end if;
f63d601b 2121
f7937111 2122 -- Derived subtypes do not have a partial view
f63d601b 2123
f7937111 2124 if Present (Priv_Typ) then
f63d601b 2125
f7937111
GD
2126 -- The processing of the "full" DIC procedure intentionally
2127 -- skips the partial view because a) this may result in changes of
2128 -- visibility and b) lead to duplicate checks. However, when the
2129 -- full view is the underlying full view of an untagged derived
2130 -- type whose parent type is private, partial DICs appear on
2131 -- the rep item chain of the partial view only.
2132
2133 -- package Pack_1 is
2134 -- type Root ... is private;
2135 -- private
2136 -- <full view of Root>
2137 -- end Pack_1;
2138
2139 -- with Pack_1;
2140 -- package Pack_2 is
2141 -- type Child is new Pack_1.Root with Type_DIC => ...;
2142 -- <underlying full view of Child>
2143 -- end Pack_2;
2144
2145 -- As a result, the processing of the full view must also consider
2146 -- all DICs of the partial view.
2147
2148 if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
2149 null;
2150
2151 -- Otherwise the DICs of the partial view are ignored
2152
2153 else
2154 -- Ignore the DICs of the partial view by eliminating the view
2155
2156 Priv_Typ := Empty;
2157 end if;
f63d601b 2158 end if;
b619c88e 2159
f7937111
GD
2160 -- Process inherited Default_Initial_Conditions for all parent types
2161
2162 Add_Parent_DICs (Work_Typ, Obj_Id, Stmts);
f63d601b
HK
2163 end if;
2164
2165 End_Scope;
2166
f7937111
GD
2167 -- Produce an empty completing body in the following cases:
2168 -- * Assertions are disabled
2169 -- * The DIC Assertion_Policy is Ignore
f63d601b 2170
f7937111
GD
2171 if No (Stmts) then
2172 Stmts := New_List (Make_Null_Statement (Loc));
2173 end if;
b5360737 2174
f7937111
GD
2175 -- Generate:
2176 -- procedure <Work_Typ>DIC (_object : <Work_Typ>) is
2177 -- begin
2178 -- <Stmts>
2179 -- end <Work_Typ>DIC;
b619c88e 2180
f7937111
GD
2181 Proc_Body :=
2182 Make_Subprogram_Body (Loc,
2183 Specification =>
2184 Copy_Subprogram_Spec (Parent (Proc_Id)),
2185 Declarations => Empty_List,
2186 Handled_Statement_Sequence =>
2187 Make_Handled_Sequence_Of_Statements (Loc,
2188 Statements => Stmts));
2189 Proc_Body_Id := Defining_Entity (Proc_Body);
f63d601b 2190
f7937111 2191 -- Perform minor decoration in case the body is not analyzed
5f325af2 2192
f7937111
GD
2193 Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
2194 Set_Etype (Proc_Body_Id, Standard_Void_Type);
2195 Set_Scope (Proc_Body_Id, Current_Scope);
2196 Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id));
2197 Set_SPARK_Pragma_Inherited
2198 (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id));
5f325af2 2199
f7937111 2200 -- Link both spec and body to avoid generating duplicates
f63d601b 2201
f7937111
GD
2202 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
2203 Set_Corresponding_Spec (Proc_Body, Proc_Id);
2204
2205 -- The body should not be inserted into the tree when the context
2206 -- is a generic unit because it is not part of the template.
2207 -- Note that the body must still be generated in order to resolve the
2208 -- DIC assertion expression.
2209
2210 if Inside_A_Generic then
2211 null;
2212
2213 -- Semi-insert the body into the tree for GNATprove by setting its
2214 -- Parent field. This allows for proper upstream tree traversals.
2215
2216 elsif GNATprove_Mode then
2217 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
2218
2219 -- Otherwise the body is part of the freezing actions of the working
2220 -- type.
2221
2222 else
2223 Append_Freeze_Action (Work_Typ, Proc_Body);
f63d601b
HK
2224 end if;
2225
d65a80fd 2226 <<Leave>>
9057bd6a 2227 Restore_Ghost_Region (Saved_GM, Saved_IGR);
f63d601b
HK
2228 end Build_DIC_Procedure_Body;
2229
2230 -------------------------------------
2231 -- Build_DIC_Procedure_Declaration --
2232 -------------------------------------
2233
b0bf18ad
AC
2234 -- WARNING: This routine manages Ghost regions. Return statements must be
2235 -- replaced by gotos which jump to the end of the routine and restore the
2236 -- Ghost mode.
2237
f7937111
GD
2238 procedure Build_DIC_Procedure_Declaration
2239 (Typ : Entity_Id;
2240 Partial_DIC : Boolean := False)
2241 is
f63d601b
HK
2242 Loc : constant Source_Ptr := Sloc (Typ);
2243
9057bd6a
HK
2244 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
2245 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
2246 -- Save the Ghost-related attributes to restore on exit
f9a8f910 2247
f63d601b
HK
2248 DIC_Prag : Node_Id;
2249 DIC_Typ : Entity_Id;
2250 Proc_Decl : Node_Id;
2251 Proc_Id : Entity_Id;
f7937111 2252 Proc_Nam : Name_Id;
f63d601b
HK
2253 Typ_Decl : Node_Id;
2254
2255 CRec_Typ : Entity_Id;
2256 -- The corresponding record type of Full_Typ
2257
f63d601b
HK
2258 Full_Typ : Entity_Id;
2259 -- The full view of working type
2260
2261 Obj_Id : Entity_Id;
2262 -- The _object formal parameter of the DIC procedure
2263
2264 Priv_Typ : Entity_Id;
2265 -- The partial view of working type
2266
b97813ab
EB
2267 UFull_Typ : Entity_Id;
2268 -- The underlying full view of Full_Typ
2269
f63d601b
HK
2270 Work_Typ : Entity_Id;
2271 -- The working type
2272
2273 begin
ce06d641
AC
2274 Work_Typ := Base_Type (Typ);
2275
2276 -- Do not process class-wide types as these are Itypes, but lack a first
2277 -- subtype (see below).
2278
2279 if Is_Class_Wide_Type (Work_Typ) then
2280 return;
2281
2282 -- Do not process the underlying full view of a private type. There is
2283 -- no way to get back to the partial view, plus the body will be built
2284 -- by the full view or the base type.
2285
2286 elsif Is_Underlying_Full_View (Work_Typ) then
2287 return;
f63d601b 2288
ce06d641 2289 -- Use the first subtype when dealing with various base types
f63d601b 2290
ce06d641 2291 elsif Is_Itype (Work_Typ) then
f63d601b
HK
2292 Work_Typ := First_Subtype (Work_Typ);
2293
2294 -- The input denotes the corresponding record type of a protected or a
2295 -- task type. Work with the concurrent type because the corresponding
2296 -- record type may not be visible to clients of the type.
2297
2298 elsif Ekind (Work_Typ) = E_Record_Type
2299 and then Is_Concurrent_Record_Type (Work_Typ)
2300 then
2301 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
2302 end if;
2303
d65a80fd
HK
2304 -- The working type may be subject to pragma Ghost. Set the mode now to
2305 -- ensure that the DIC procedure is properly marked as Ghost.
2306
f9a8f910 2307 Set_Ghost_Mode (Work_Typ);
d65a80fd 2308
f63d601b
HK
2309 -- The type must be either subject to a DIC pragma or inherit one from a
2310 -- parent type.
2311
2312 pragma Assert (Has_DIC (Work_Typ));
2313
2314 -- Recover the type which defines the DIC pragma. This is either the
2315 -- working type itself or a parent type when the pragma is inherited.
2316
2317 DIC_Typ := Find_DIC_Type (Work_Typ);
2318 pragma Assert (Present (DIC_Typ));
2319
2320 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition);
2321 pragma Assert (Present (DIC_Prag));
2322
2323 -- Nothing to do if pragma DIC appears without an argument or its sole
2324 -- argument is "null".
2325
2326 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then
d65a80fd 2327 goto Leave;
f7937111
GD
2328 end if;
2329
2330 -- Nothing to do if the type already has a "partial" DIC procedure
2331
2332 if Partial_DIC then
2333 if Present (Partial_DIC_Procedure (Work_Typ)) then
2334 goto Leave;
2335 end if;
f63d601b 2336
f7937111 2337 -- Nothing to do if the type already has a "full" DIC procedure
f63d601b
HK
2338
2339 elsif Present (DIC_Procedure (Work_Typ)) then
d65a80fd 2340 goto Leave;
f63d601b
HK
2341 end if;
2342
f7937111
GD
2343 -- The caller requests the declaration of the "partial" DIC procedure
2344
2345 if Partial_DIC then
2346 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_DIC");
2347
2348 -- Otherwise the caller requests the declaration of the "full" DIC
2349 -- procedure.
2350
2351 else
2352 Proc_Nam := New_External_Name (Chars (Work_Typ), "DIC");
2353 end if;
2354
f63d601b 2355 Proc_Id :=
f7937111 2356 Make_Defining_Identifier (Loc, Chars => Proc_Nam);
f63d601b
HK
2357
2358 -- Perform minor decoration in case the declaration is not analyzed
2359
90e491a7
PMR
2360 Set_Ekind (Proc_Id, E_Procedure);
2361 Set_Etype (Proc_Id, Standard_Void_Type);
2362 Set_Is_DIC_Procedure (Proc_Id);
2363 Set_Scope (Proc_Id, Current_Scope);
2364 Set_SPARK_Pragma (Proc_Id, SPARK_Mode_Pragma);
2365 Set_SPARK_Pragma_Inherited (Proc_Id);
f63d601b 2366
f63d601b
HK
2367 Set_DIC_Procedure (Work_Typ, Proc_Id);
2368
2369 -- The DIC procedure requires debug info when the assertion expression
2370 -- is subject to Source Coverage Obligations.
2371
90e491a7 2372 if Generate_SCO then
923ecd0e 2373 Set_Debug_Info_Needed (Proc_Id);
f63d601b
HK
2374 end if;
2375
f63d601b
HK
2376 -- Obtain all views of the input type
2377
b97813ab 2378 Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);
f63d601b 2379
b97813ab 2380 -- Associate the DIC procedure and various flags with all views
f63d601b
HK
2381
2382 Propagate_DIC_Attributes (Priv_Typ, From_Typ => Work_Typ);
2383 Propagate_DIC_Attributes (Full_Typ, From_Typ => Work_Typ);
b97813ab 2384 Propagate_DIC_Attributes (UFull_Typ, From_Typ => Work_Typ);
f63d601b
HK
2385 Propagate_DIC_Attributes (CRec_Typ, From_Typ => Work_Typ);
2386
2387 -- The declaration of the DIC procedure must be inserted after the
2388 -- declaration of the partial view as this allows for proper external
2389 -- visibility.
2390
2391 if Present (Priv_Typ) then
2392 Typ_Decl := Declaration_Node (Priv_Typ);
2393
2394 -- Derived types with the full view as parent do not have a partial
2395 -- view. Insert the DIC procedure after the derived type.
2396
2397 else
2398 Typ_Decl := Declaration_Node (Full_Typ);
2399 end if;
2400
2401 -- The type should have a declarative node
2402
2403 pragma Assert (Present (Typ_Decl));
2404
2405 -- Create the formal parameter which emulates the variable-like behavior
e51102b2 2406 -- of the type's current instance.
f63d601b
HK
2407
2408 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
2409
2410 -- Perform minor decoration in case the declaration is not analyzed
2411
2412 Set_Ekind (Obj_Id, E_In_Parameter);
2413 Set_Etype (Obj_Id, Work_Typ);
2414 Set_Scope (Obj_Id, Proc_Id);
2415
2416 Set_First_Entity (Proc_Id, Obj_Id);
aa090e20 2417 Set_Last_Entity (Proc_Id, Obj_Id);
f63d601b
HK
2418
2419 -- Generate:
2420 -- procedure <Work_Typ>DIC (_object : <Work_Typ>);
2421
2422 Proc_Decl :=
2423 Make_Subprogram_Declaration (Loc,
2424 Specification =>
2425 Make_Procedure_Specification (Loc,
2426 Defining_Unit_Name => Proc_Id,
2427 Parameter_Specifications => New_List (
2428 Make_Parameter_Specification (Loc,
2429 Defining_Identifier => Obj_Id,
2430 Parameter_Type =>
2431 New_Occurrence_Of (Work_Typ, Loc)))));
2432
2433 -- The declaration should not be inserted into the tree when the context
65f1ca2e 2434 -- is a generic unit because it is not part of the template.
f63d601b 2435
65f1ca2e 2436 if Inside_A_Generic then
f63d601b
HK
2437 null;
2438
5f325af2
AC
2439 -- Semi-insert the declaration into the tree for GNATprove by setting
2440 -- its Parent field. This allows for proper upstream tree traversals.
2441
2442 elsif GNATprove_Mode then
2443 Set_Parent (Proc_Decl, Parent (Typ_Decl));
2444
f63d601b
HK
2445 -- Otherwise insert the declaration
2446
2447 else
f63d601b
HK
2448 Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
2449 end if;
2450
d65a80fd 2451 <<Leave>>
9057bd6a 2452 Restore_Ghost_Region (Saved_GM, Saved_IGR);
f63d601b
HK
2453 end Build_DIC_Procedure_Declaration;
2454
51148dda
AC
2455 ------------------------------------
2456 -- Build_Invariant_Procedure_Body --
2457 ------------------------------------
2458
2459 -- WARNING: This routine manages Ghost regions. Return statements must be
2460 -- replaced by gotos which jump to the end of the routine and restore the
2461 -- Ghost mode.
2462
2463 procedure Build_Invariant_Procedure_Body
2464 (Typ : Entity_Id;
2465 Partial_Invariant : Boolean := False)
2466 is
2467 Loc : constant Source_Ptr := Sloc (Typ);
2468
2469 Pragmas_Seen : Elist_Id := No_Elist;
2470 -- This list contains all invariant pragmas processed so far. The list
2471 -- is used to avoid generating redundant invariant checks.
2472
2473 Produced_Check : Boolean := False;
2474 -- This flag tracks whether the type has produced at least one invariant
2475 -- check. The flag is used as a sanity check at the end of the routine.
2476
2477 -- NOTE: most of the routines in Build_Invariant_Procedure_Body are
2478 -- intentionally unnested to avoid deep indentation of code.
2479
2480 -- NOTE: all Add_xxx_Invariants routines are reactive. In other words
2481 -- they emit checks, loops (for arrays) and case statements (for record
2482 -- variant parts) only when there are invariants to verify. This keeps
b554177a 2483 -- the body of the invariant procedure free of useless code.
51148dda
AC
2484
2485 procedure Add_Array_Component_Invariants
2486 (T : Entity_Id;
2487 Obj_Id : Entity_Id;
2488 Checks : in out List_Id);
2489 -- Generate an invariant check for each component of array type T.
2490 -- Obj_Id denotes the entity of the _object formal parameter of the
2491 -- invariant procedure. All created checks are added to list Checks.
2492
003d46d5 2493 procedure Add_Inherited_Invariants
b554177a
AC
2494 (T : Entity_Id;
2495 Priv_Typ : Entity_Id;
2496 Full_Typ : Entity_Id;
2497 Obj_Id : Entity_Id;
2498 Checks : in out List_Id);
ded462b0 2499 -- Generate an invariant check for each inherited class-wide invariant
b554177a
AC
2500 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote
2501 -- the partial and full view of the parent type. Obj_Id denotes the
2502 -- entity of the _object formal parameter of the invariant procedure.
2503 -- All created checks are added to list Checks.
ded462b0
AC
2504
2505 procedure Add_Interface_Invariants
2506 (T : Entity_Id;
2507 Obj_Id : Entity_Id;
2508 Checks : in out List_Id);
2509 -- Generate an invariant check for each inherited class-wide invariant
2510 -- coming from all interfaces implemented by type T. Obj_Id denotes the
2511 -- entity of the _object formal parameter of the invariant procedure.
2512 -- All created checks are added to list Checks.
2513
998429d6
AC
2514 procedure Add_Invariant_Check
2515 (Prag : Node_Id;
2516 Expr : Node_Id;
2517 Checks : in out List_Id;
2518 Inherited : Boolean := False);
2519 -- Subsidiary to all Add_xxx_Invariant routines. Add a runtime check to
2520 -- verify assertion expression Expr of pragma Prag. All generated code
2521 -- is added to list Checks. Flag Inherited should be set when the pragma
2522 -- is inherited from a parent or interface type.
51148dda 2523
003d46d5 2524 procedure Add_Own_Invariants
998429d6
AC
2525 (T : Entity_Id;
2526 Obj_Id : Entity_Id;
2527 Checks : in out List_Id;
2528 Priv_Item : Node_Id := Empty);
2529 -- Generate an invariant check for each invariant found for type T.
2530 -- Obj_Id denotes the entity of the _object formal parameter of the
2531 -- invariant procedure. All created checks are added to list Checks.
2532 -- Priv_Item denotes the first rep item of the private type.
2533
ded462b0
AC
2534 procedure Add_Parent_Invariants
2535 (T : Entity_Id;
2536 Obj_Id : Entity_Id;
2537 Checks : in out List_Id);
2538 -- Generate an invariant check for each inherited class-wide invariant
2539 -- coming from all parent types of type T. Obj_Id denotes the entity of
2540 -- the _object formal parameter of the invariant procedure. All created
2541 -- checks are added to list Checks.
2542
51148dda
AC
2543 procedure Add_Record_Component_Invariants
2544 (T : Entity_Id;
2545 Obj_Id : Entity_Id;
2546 Checks : in out List_Id);
2547 -- Generate an invariant check for each component of record type T.
2548 -- Obj_Id denotes the entity of the _object formal parameter of the
2549 -- invariant procedure. All created checks are added to list Checks.
2550
51148dda
AC
2551 ------------------------------------
2552 -- Add_Array_Component_Invariants --
2553 ------------------------------------
2554
2555 procedure Add_Array_Component_Invariants
2556 (T : Entity_Id;
2557 Obj_Id : Entity_Id;
2558 Checks : in out List_Id)
2559 is
2560 Comp_Typ : constant Entity_Id := Component_Type (T);
2561 Dims : constant Pos := Number_Dimensions (T);
2562
2563 procedure Process_Array_Component
2564 (Indices : List_Id;
2565 Comp_Checks : in out List_Id);
2566 -- Generate an invariant check for an array component identified by
2567 -- the indices in list Indices. All created checks are added to list
2568 -- Comp_Checks.
2569
2570 procedure Process_One_Dimension
2571 (Dim : Pos;
2572 Indices : List_Id;
2573 Dim_Checks : in out List_Id);
2574 -- Generate a loop over the Nth dimension Dim of an array type. List
2575 -- Indices contains all array indices for the dimension. All created
2576 -- checks are added to list Dim_Checks.
2577
2578 -----------------------------
2579 -- Process_Array_Component --
2580 -----------------------------
2581
2582 procedure Process_Array_Component
2583 (Indices : List_Id;
2584 Comp_Checks : in out List_Id)
2585 is
2586 Proc_Id : Entity_Id;
2587
2588 begin
2589 if Has_Invariants (Comp_Typ) then
2590
2591 -- In GNATprove mode, the component invariants are checked by
2592 -- other means. They should not be added to the array type
2593 -- invariant procedure, so that the procedure can be used to
2594 -- check the array type invariants if any.
2595
2596 if GNATprove_Mode then
2597 null;
2598
2599 else
2600 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
2601
2602 -- The component type should have an invariant procedure
2603 -- if it has invariants of its own or inherits class-wide
2604 -- invariants from parent or interface types.
2605
2606 pragma Assert (Present (Proc_Id));
2607
2608 -- Generate:
2609 -- <Comp_Typ>Invariant (_object (<Indices>));
2610
b9daf13c
BD
2611 -- The invariant procedure has a null body if assertions are
2612 -- disabled or Assertion_Policy Ignore is in effect.
51148dda
AC
2613
2614 if not Has_Null_Body (Proc_Id) then
2615 Append_New_To (Comp_Checks,
2616 Make_Procedure_Call_Statement (Loc,
2617 Name =>
2618 New_Occurrence_Of (Proc_Id, Loc),
2619 Parameter_Associations => New_List (
2620 Make_Indexed_Component (Loc,
2621 Prefix => New_Occurrence_Of (Obj_Id, Loc),
2622 Expressions => New_Copy_List (Indices)))));
2623 end if;
2624 end if;
2625
2626 Produced_Check := True;
2627 end if;
2628 end Process_Array_Component;
2629
2630 ---------------------------
2631 -- Process_One_Dimension --
2632 ---------------------------
2633
2634 procedure Process_One_Dimension
2635 (Dim : Pos;
2636 Indices : List_Id;
2637 Dim_Checks : in out List_Id)
2638 is
2639 Comp_Checks : List_Id := No_List;
2640 Index : Entity_Id;
2641
2642 begin
2643 -- Generate the invariant checks for the array component after all
2644 -- dimensions have produced their respective loops.
2645
2646 if Dim > Dims then
2647 Process_Array_Component
2648 (Indices => Indices,
2649 Comp_Checks => Dim_Checks);
2650
2651 -- Otherwise create a loop for the current dimension
2652
2653 else
2654 -- Create a new loop variable for each dimension
2655
2656 Index :=
2657 Make_Defining_Identifier (Loc,
2658 Chars => New_External_Name ('I', Dim));
2659 Append_To (Indices, New_Occurrence_Of (Index, Loc));
2660
2661 Process_One_Dimension
2662 (Dim => Dim + 1,
2663 Indices => Indices,
2664 Dim_Checks => Comp_Checks);
2665
2666 -- Generate:
2667 -- for I<Dim> in _object'Range (<Dim>) loop
2668 -- <Comp_Checks>
2669 -- end loop;
2670
2671 -- Note that the invariant procedure may have a null body if
2672 -- assertions are disabled or Assertion_Policy Ignore is in
2673 -- effect.
2674
2675 if Present (Comp_Checks) then
2676 Append_New_To (Dim_Checks,
2677 Make_Implicit_Loop_Statement (T,
2678 Identifier => Empty,
2679 Iteration_Scheme =>
2680 Make_Iteration_Scheme (Loc,
2681 Loop_Parameter_Specification =>
2682 Make_Loop_Parameter_Specification (Loc,
2683 Defining_Identifier => Index,
2684 Discrete_Subtype_Definition =>
2685 Make_Attribute_Reference (Loc,
2686 Prefix =>
2687 New_Occurrence_Of (Obj_Id, Loc),
2688 Attribute_Name => Name_Range,
2689 Expressions => New_List (
2690 Make_Integer_Literal (Loc, Dim))))),
998429d6 2691 Statements => Comp_Checks));
51148dda
AC
2692 end if;
2693 end if;
2694 end Process_One_Dimension;
2695
2696 -- Start of processing for Add_Array_Component_Invariants
2697
2698 begin
2699 Process_One_Dimension
2700 (Dim => 1,
2701 Indices => New_List,
2702 Dim_Checks => Checks);
2703 end Add_Array_Component_Invariants;
2704
003d46d5
AC
2705 ------------------------------
2706 -- Add_Inherited_Invariants --
2707 ------------------------------
51148dda 2708
003d46d5 2709 procedure Add_Inherited_Invariants
b554177a
AC
2710 (T : Entity_Id;
2711 Priv_Typ : Entity_Id;
2712 Full_Typ : Entity_Id;
2713 Obj_Id : Entity_Id;
2714 Checks : in out List_Id)
51148dda 2715 is
b554177a
AC
2716 Deriv_Typ : Entity_Id;
2717 Expr : Node_Id;
2718 Prag : Node_Id;
2719 Prag_Expr : Node_Id;
2720 Prag_Expr_Arg : Node_Id;
2721 Prag_Typ : Node_Id;
2722 Prag_Typ_Arg : Node_Id;
2723
2724 Par_Proc : Entity_Id;
2725 -- The "partial" invariant procedure of Par_Typ
998429d6 2726
b554177a
AC
2727 Par_Typ : Entity_Id;
2728 -- The suitable view of the parent type used in the substitution of
2729 -- type attributes.
51148dda
AC
2730
2731 begin
ded462b0 2732 if not Present (Priv_Typ) and then not Present (Full_Typ) then
998429d6
AC
2733 return;
2734 end if;
51148dda 2735
5f8d3dd5
AC
2736 -- When the type inheriting the class-wide invariant is a concurrent
2737 -- type, use the corresponding record type because it contains all
ca0b6141 2738 -- primitive operations of the concurrent type and allows for proper
5f8d3dd5
AC
2739 -- substitution.
2740
2741 if Is_Concurrent_Type (T) then
2742 Deriv_Typ := Corresponding_Record_Type (T);
2743 else
2744 Deriv_Typ := T;
2745 end if;
2746
a8531f71 2747 pragma Assert (Present (Deriv_Typ));
5f8d3dd5 2748
b554177a
AC
2749 -- Determine which rep item chain to use. Precedence is given to that
2750 -- of the parent type's partial view since it usually carries all the
2751 -- class-wide invariants.
2752
ded462b0
AC
2753 if Present (Priv_Typ) then
2754 Prag := First_Rep_Item (Priv_Typ);
2755 else
2756 Prag := First_Rep_Item (Full_Typ);
2757 end if;
2758
998429d6
AC
2759 while Present (Prag) loop
2760 if Nkind (Prag) = N_Pragma
2761 and then Pragma_Name (Prag) = Name_Invariant
2762 then
2763 -- Nothing to do if the pragma was already processed
51148dda 2764
998429d6
AC
2765 if Contains (Pragmas_Seen, Prag) then
2766 return;
b554177a
AC
2767
2768 -- Nothing to do when the caller requests the processing of all
2769 -- inherited class-wide invariants, but the pragma does not
2770 -- fall in this category.
2771
2772 elsif not Class_Present (Prag) then
2773 return;
998429d6 2774 end if;
51148dda 2775
998429d6 2776 -- Extract the arguments of the invariant pragma
51148dda 2777
b554177a
AC
2778 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag));
2779 Prag_Expr_Arg := Next (Prag_Typ_Arg);
2780 Prag_Expr := Expression_Copy (Prag_Expr_Arg);
2781 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
ded462b0 2782
b554177a 2783 -- The pragma applies to the partial view of the parent type
ded462b0 2784
b554177a
AC
2785 if Present (Priv_Typ)
2786 and then Entity (Prag_Typ) = Priv_Typ
2787 then
2788 Par_Typ := Priv_Typ;
ded462b0 2789
b554177a 2790 -- The pragma applies to the full view of the parent type
ded462b0 2791
b554177a
AC
2792 elsif Present (Full_Typ)
2793 and then Entity (Prag_Typ) = Full_Typ
2794 then
2795 Par_Typ := Full_Typ;
998429d6 2796
b554177a
AC
2797 -- Otherwise the pragma does not belong to the parent type and
2798 -- should not be considered.
51148dda 2799
998429d6
AC
2800 else
2801 return;
2802 end if;
51148dda 2803
b554177a 2804 -- Perform the following substitutions:
998429d6 2805
b554177a
AC
2806 -- * Replace a reference to the _object parameter of the
2807 -- parent type's partial invariant procedure with a
2808 -- reference to the _object parameter of the derived
2809 -- type's full invariant procedure.
2810
2811 -- * Replace a reference to a discriminant of the parent type
2812 -- with a suitable value from the point of view of the
2813 -- derived type.
2814
2815 -- * Replace a call to an overridden parent primitive with a
2816 -- call to the overriding derived type primitive.
2817
2818 -- * Replace a call to an inherited parent primitive with a
2819 -- call to the internally-generated inherited derived type
2820 -- primitive.
2821
2822 Expr := New_Copy_Tree (Prag_Expr);
2823
b554177a
AC
2824 -- The parent type must have a "partial" invariant procedure
2825 -- because class-wide invariants are captured exclusively by
2826 -- it.
998429d6 2827
b554177a
AC
2828 Par_Proc := Partial_Invariant_Procedure (Par_Typ);
2829 pragma Assert (Present (Par_Proc));
998429d6 2830
b554177a
AC
2831 Replace_References
2832 (Expr => Expr,
2833 Par_Typ => Par_Typ,
2834 Deriv_Typ => Deriv_Typ,
2835 Par_Obj => First_Formal (Par_Proc),
2836 Deriv_Obj => Obj_Id);
998429d6
AC
2837
2838 Add_Invariant_Check (Prag, Expr, Checks, Inherited => True);
2839 end if;
2840
2841 Next_Rep_Item (Prag);
2842 end loop;
003d46d5 2843 end Add_Inherited_Invariants;
998429d6 2844
ded462b0
AC
2845 ------------------------------
2846 -- Add_Interface_Invariants --
2847 ------------------------------
2848
2849 procedure Add_Interface_Invariants
2850 (T : Entity_Id;
2851 Obj_Id : Entity_Id;
2852 Checks : in out List_Id)
2853 is
2854 Iface_Elmt : Elmt_Id;
2855 Ifaces : Elist_Id;
2856
2857 begin
003d46d5
AC
2858 -- Generate an invariant check for each class-wide invariant coming
2859 -- from all interfaces implemented by type T.
ded462b0
AC
2860
2861 if Is_Tagged_Type (T) then
2862 Collect_Interfaces (T, Ifaces);
2863
2864 -- Process the class-wide invariants of all implemented interfaces
2865
2866 Iface_Elmt := First_Elmt (Ifaces);
2867 while Present (Iface_Elmt) loop
b554177a
AC
2868
2869 -- The Full_Typ parameter is intentionally left Empty because
2870 -- interfaces are treated as the partial view of a private type
2871 -- in order to achieve uniformity with the general case.
2872
003d46d5 2873 Add_Inherited_Invariants
b554177a
AC
2874 (T => T,
2875 Priv_Typ => Node (Iface_Elmt),
2876 Full_Typ => Empty,
2877 Obj_Id => Obj_Id,
2878 Checks => Checks);
ded462b0
AC
2879
2880 Next_Elmt (Iface_Elmt);
2881 end loop;
2882 end if;
2883 end Add_Interface_Invariants;
2884
998429d6
AC
2885 -------------------------
2886 -- Add_Invariant_Check --
2887 -------------------------
2888
2889 procedure Add_Invariant_Check
2890 (Prag : Node_Id;
2891 Expr : Node_Id;
2892 Checks : in out List_Id;
2893 Inherited : Boolean := False)
2894 is
2895 Args : constant List_Id := Pragma_Argument_Associations (Prag);
2896 Nam : constant Name_Id := Original_Aspect_Pragma_Name (Prag);
2897 Ploc : constant Source_Ptr := Sloc (Prag);
2898 Str_Arg : constant Node_Id := Next (Next (First (Args)));
2899
2900 Assoc : List_Id;
2901 Str : String_Id;
51148dda
AC
2902
2903 begin
998429d6
AC
2904 -- The invariant is ignored, nothing left to do
2905
2906 if Is_Ignored (Prag) then
2907 null;
2908
b554177a 2909 -- Otherwise the invariant is checked. Build a pragma Check to verify
ca0b6141 2910 -- the expression at run time.
998429d6
AC
2911
2912 else
2913 Assoc := New_List (
2914 Make_Pragma_Argument_Association (Ploc,
2915 Expression => Make_Identifier (Ploc, Nam)),
2916 Make_Pragma_Argument_Association (Ploc,
2917 Expression => Expr));
2918
2919 -- Handle the String argument (if any)
2920
2921 if Present (Str_Arg) then
2922 Str := Strval (Get_Pragma_Arg (Str_Arg));
2923
2924 -- When inheriting an invariant, modify the message from
2925 -- "failed invariant" to "failed inherited invariant".
2926
2927 if Inherited then
2928 String_To_Name_Buffer (Str);
2929
2930 if Name_Buffer (1 .. 16) = "failed invariant" then
2931 Insert_Str_In_Name_Buffer ("inherited ", 8);
2932 Str := String_From_Name_Buffer;
2933 end if;
2934 end if;
2935
2936 Append_To (Assoc,
2937 Make_Pragma_Argument_Association (Ploc,
2938 Expression => Make_String_Literal (Ploc, Str)));
2939 end if;
2940
2941 -- Generate:
2942 -- pragma Check (<Nam>, <Expr>, <Str>);
2943
2944 Append_New_To (Checks,
2945 Make_Pragma (Ploc,
2946 Chars => Name_Check,
2947 Pragma_Argument_Associations => Assoc));
2948 end if;
2949
2950 -- Output an info message when inheriting an invariant and the
2951 -- listing option is enabled.
2952
2953 if Inherited and Opt.List_Inherited_Aspects then
2954 Error_Msg_Sloc := Sloc (Prag);
2955 Error_Msg_N
2956 ("info: & inherits `Invariant''Class` aspect from #?L?", Typ);
2957 end if;
2958
2959 -- Add the pragma to the list of processed pragmas
2960
2961 Append_New_Elmt (Prag, Pragmas_Seen);
2962 Produced_Check := True;
2963 end Add_Invariant_Check;
2964
ded462b0
AC
2965 ---------------------------
2966 -- Add_Parent_Invariants --
2967 ---------------------------
2968
2969 procedure Add_Parent_Invariants
2970 (T : Entity_Id;
2971 Obj_Id : Entity_Id;
2972 Checks : in out List_Id)
2973 is
2974 Dummy_1 : Entity_Id;
2975 Dummy_2 : Entity_Id;
2976
2977 Curr_Typ : Entity_Id;
2978 -- The entity of the current type being examined
2979
2980 Full_Typ : Entity_Id;
2981 -- The full view of Par_Typ
2982
2983 Par_Typ : Entity_Id;
2984 -- The entity of the parent type
2985
2986 Priv_Typ : Entity_Id;
2987 -- The partial view of Par_Typ
2988
2989 begin
2990 -- Do not process array types because they cannot have true parent
2991 -- types. This also prevents the generation of a duplicate invariant
2992 -- check when the input type is an array base type because its Etype
2993 -- denotes the first subtype, both of which share the same component
2994 -- type.
2995
2996 if Is_Array_Type (T) then
2997 return;
2998 end if;
2999
3000 -- Climb the parent type chain
3001
3002 Curr_Typ := T;
3003 loop
3004 -- Do not consider subtypes as they inherit the invariants
3005 -- from their base types.
3006
3007 Par_Typ := Base_Type (Etype (Curr_Typ));
3008
3009 -- Stop the climb once the root of the parent chain is
3010 -- reached.
3011
3012 exit when Curr_Typ = Par_Typ;
3013
3014 -- Process the class-wide invariants of the parent type
3015
3016 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2);
3017
3018 -- Process the elements of an array type
3019
3020 if Is_Array_Type (Full_Typ) then
3021 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Checks);
3022
3023 -- Process the components of a record type
3024
3025 elsif Ekind (Full_Typ) = E_Record_Type then
3026 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Checks);
3027 end if;
3028
003d46d5 3029 Add_Inherited_Invariants
b554177a
AC
3030 (T => T,
3031 Priv_Typ => Priv_Typ,
3032 Full_Typ => Full_Typ,
3033 Obj_Id => Obj_Id,
3034 Checks => Checks);
ded462b0
AC
3035
3036 Curr_Typ := Par_Typ;
3037 end loop;
3038 end Add_Parent_Invariants;
3039
003d46d5
AC
3040 ------------------------
3041 -- Add_Own_Invariants --
3042 ------------------------
998429d6 3043
003d46d5 3044 procedure Add_Own_Invariants
998429d6
AC
3045 (T : Entity_Id;
3046 Obj_Id : Entity_Id;
3047 Checks : in out List_Id;
3048 Priv_Item : Node_Id := Empty)
3049 is
b554177a
AC
3050 Expr : Node_Id;
3051 Prag : Node_Id;
3052 Prag_Asp : Node_Id;
3053 Prag_Expr : Node_Id;
3054 Prag_Expr_Arg : Node_Id;
3055 Prag_Typ : Node_Id;
3056 Prag_Typ_Arg : Node_Id;
51148dda 3057
998429d6
AC
3058 begin
3059 if not Present (T) then
51148dda
AC
3060 return;
3061 end if;
3062
998429d6
AC
3063 Prag := First_Rep_Item (T);
3064 while Present (Prag) loop
3065 if Nkind (Prag) = N_Pragma
3066 and then Pragma_Name (Prag) = Name_Invariant
3067 then
3068 -- Stop the traversal of the rep item chain once a specific
3069 -- item is encountered.
51148dda 3070
998429d6
AC
3071 if Present (Priv_Item) and then Prag = Priv_Item then
3072 exit;
3073 end if;
3074
3075 -- Nothing to do if the pragma was already processed
3076
3077 if Contains (Pragmas_Seen, Prag) then
3078 return;
3079 end if;
3080
3081 -- Extract the arguments of the invariant pragma
3082
b554177a
AC
3083 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag));
3084 Prag_Expr_Arg := Next (Prag_Typ_Arg);
3085 Prag_Expr := Get_Pragma_Arg (Prag_Expr_Arg);
3086 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg);
3087 Prag_Asp := Corresponding_Aspect (Prag);
998429d6 3088
ded462b0 3089 -- Verify the pragma belongs to T, otherwise the pragma applies
003d46d5
AC
3090 -- to a parent type in which case it will be processed later by
3091 -- Add_Parent_Invariants or Add_Interface_Invariants.
998429d6 3092
b554177a 3093 if Entity (Prag_Typ) /= T then
998429d6
AC
3094 return;
3095 end if;
3096
b554177a 3097 Expr := New_Copy_Tree (Prag_Expr);
998429d6 3098
003d46d5
AC
3099 -- Substitute all references to type T with references to the
3100 -- _object formal parameter.
998429d6 3101
b554177a 3102 Replace_Type_References (Expr, T, Obj_Id);
998429d6
AC
3103
3104 -- Preanalyze the invariant expression to detect errors and at
3105 -- the same time capture the visibility of the proper package
3106 -- part.
51148dda 3107
b554177a 3108 Set_Parent (Expr, Parent (Prag_Expr));
998429d6 3109 Preanalyze_Assert_Expression (Expr, Any_Boolean);
51148dda 3110
b554177a
AC
3111 -- Save a copy of the expression when T is tagged to detect
3112 -- errors and capture the visibility of the proper package part
3113 -- for the generation of inherited type invariants.
3114
3115 if Is_Tagged_Type (T) then
3116 Set_Expression_Copy (Prag_Expr_Arg, New_Copy_Tree (Expr));
3117 end if;
3118
998429d6
AC
3119 -- If the pragma comes from an aspect specification, replace
3120 -- the saved expression because all type references must be
3121 -- substituted for the call to Preanalyze_Spec_Expression in
3122 -- Check_Aspect_At_xxx routines.
51148dda 3123
b554177a
AC
3124 if Present (Prag_Asp) then
3125 Set_Entity (Identifier (Prag_Asp), New_Copy_Tree (Expr));
998429d6
AC
3126 end if;
3127
998429d6
AC
3128 Add_Invariant_Check (Prag, Expr, Checks);
3129 end if;
3130
3131 Next_Rep_Item (Prag);
51148dda 3132 end loop;
003d46d5 3133 end Add_Own_Invariants;
51148dda
AC
3134
3135 -------------------------------------
3136 -- Add_Record_Component_Invariants --
3137 -------------------------------------
3138
3139 procedure Add_Record_Component_Invariants
3140 (T : Entity_Id;
3141 Obj_Id : Entity_Id;
3142 Checks : in out List_Id)
3143 is
3144 procedure Process_Component_List
3145 (Comp_List : Node_Id;
3146 CL_Checks : in out List_Id);
3147 -- Generate invariant checks for all record components found in
3148 -- component list Comp_List, including variant parts. All created
3149 -- checks are added to list CL_Checks.
3150
3151 procedure Process_Record_Component
3152 (Comp_Id : Entity_Id;
3153 Comp_Checks : in out List_Id);
3154 -- Generate an invariant check for a record component identified by
3155 -- Comp_Id. All created checks are added to list Comp_Checks.
3156
3157 ----------------------------
3158 -- Process_Component_List --
3159 ----------------------------
3160
3161 procedure Process_Component_List
3162 (Comp_List : Node_Id;
3163 CL_Checks : in out List_Id)
3164 is
3165 Comp : Node_Id;
3166 Var : Node_Id;
3167 Var_Alts : List_Id := No_List;
3168 Var_Checks : List_Id := No_List;
3169 Var_Stmts : List_Id;
3170
3171 Produced_Variant_Check : Boolean := False;
3172 -- This flag tracks whether the component has produced at least
3173 -- one invariant check.
3174
3175 begin
3176 -- Traverse the component items
3177
3178 Comp := First (Component_Items (Comp_List));
3179 while Present (Comp) loop
3180 if Nkind (Comp) = N_Component_Declaration then
3181
3182 -- Generate the component invariant check
3183
3184 Process_Record_Component
3185 (Comp_Id => Defining_Entity (Comp),
3186 Comp_Checks => CL_Checks);
3187 end if;
3188
3189 Next (Comp);
3190 end loop;
3191
3192 -- Traverse the variant part
3193
3194 if Present (Variant_Part (Comp_List)) then
3195 Var := First (Variants (Variant_Part (Comp_List)));
3196 while Present (Var) loop
3197 Var_Checks := No_List;
3198
3199 -- Generate invariant checks for all components and variant
3200 -- parts that qualify.
3201
3202 Process_Component_List
3203 (Comp_List => Component_List (Var),
3204 CL_Checks => Var_Checks);
3205
3206 -- The components of the current variant produced at least
3207 -- one invariant check.
3208
3209 if Present (Var_Checks) then
3210 Var_Stmts := Var_Checks;
3211 Produced_Variant_Check := True;
3212
3213 -- Otherwise there are either no components with invariants,
3214 -- assertions are disabled, or Assertion_Policy Ignore is in
3215 -- effect.
3216
3217 else
3218 Var_Stmts := New_List (Make_Null_Statement (Loc));
3219 end if;
3220
3221 Append_New_To (Var_Alts,
3222 Make_Case_Statement_Alternative (Loc,
3223 Discrete_Choices =>
3224 New_Copy_List (Discrete_Choices (Var)),
3225 Statements => Var_Stmts));
3226
3227 Next (Var);
3228 end loop;
3229
3230 -- Create a case statement which verifies the invariant checks
3231 -- of a particular component list depending on the discriminant
3232 -- values only when there is at least one real invariant check.
3233
3234 if Produced_Variant_Check then
3235 Append_New_To (CL_Checks,
3236 Make_Case_Statement (Loc,
3237 Expression =>
3238 Make_Selected_Component (Loc,
3239 Prefix => New_Occurrence_Of (Obj_Id, Loc),
3240 Selector_Name =>
3241 New_Occurrence_Of
3242 (Entity (Name (Variant_Part (Comp_List))), Loc)),
3243 Alternatives => Var_Alts));
3244 end if;
3245 end if;
3246 end Process_Component_List;
3247
3248 ------------------------------
3249 -- Process_Record_Component --
3250 ------------------------------
3251
3252 procedure Process_Record_Component
3253 (Comp_Id : Entity_Id;
3254 Comp_Checks : in out List_Id)
3255 is
3256 Comp_Typ : constant Entity_Id := Etype (Comp_Id);
3257 Proc_Id : Entity_Id;
3258
3259 Produced_Component_Check : Boolean := False;
3260 -- This flag tracks whether the component has produced at least
3261 -- one invariant check.
3262
3263 begin
3264 -- Nothing to do for internal component _parent. Note that it is
3265 -- not desirable to check whether the component comes from source
3266 -- because protected type components are relocated to an internal
3267 -- corresponding record, but still need processing.
3268
3269 if Chars (Comp_Id) = Name_uParent then
3270 return;
3271 end if;
3272
3273 -- Verify the invariant of the component. Note that an access
3274 -- type may have an invariant when it acts as the full view of a
3275 -- private type and the invariant appears on the partial view. In
3276 -- this case verify the access value itself.
3277
3278 if Has_Invariants (Comp_Typ) then
3279
3280 -- In GNATprove mode, the component invariants are checked by
3281 -- other means. They should not be added to the record type
3282 -- invariant procedure, so that the procedure can be used to
3283 -- check the record type invariants if any.
3284
3285 if GNATprove_Mode then
3286 null;
3287
3288 else
3289 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ));
3290
3291 -- The component type should have an invariant procedure
3292 -- if it has invariants of its own or inherits class-wide
3293 -- invariants from parent or interface types.
3294
3295 pragma Assert (Present (Proc_Id));
3296
3297 -- Generate:
3298 -- <Comp_Typ>Invariant (T (_object).<Comp_Id>);
3299
3300 -- Note that the invariant procedure may have a null body if
3301 -- assertions are disabled or Assertion_Policy Ignore is in
3302 -- effect.
3303
3304 if not Has_Null_Body (Proc_Id) then
3305 Append_New_To (Comp_Checks,
3306 Make_Procedure_Call_Statement (Loc,
3307 Name =>
3308 New_Occurrence_Of (Proc_Id, Loc),
3309 Parameter_Associations => New_List (
3310 Make_Selected_Component (Loc,
3311 Prefix =>
3312 Unchecked_Convert_To
3313 (T, New_Occurrence_Of (Obj_Id, Loc)),
3314 Selector_Name =>
3315 New_Occurrence_Of (Comp_Id, Loc)))));
3316 end if;
3317 end if;
3318
3319 Produced_Check := True;
3320 Produced_Component_Check := True;
3321 end if;
3322
3323 if Produced_Component_Check and then Has_Unchecked_Union (T) then
3324 Error_Msg_NE
3325 ("invariants cannot be checked on components of "
2d6f6e08 3326 & "unchecked_union type &??", Comp_Id, T);
51148dda
AC
3327 end if;
3328 end Process_Record_Component;
3329
3330 -- Local variables
3331
3332 Comps : Node_Id;
3333 Def : Node_Id;
3334
3335 -- Start of processing for Add_Record_Component_Invariants
3336
3337 begin
3338 -- An untagged derived type inherits the components of its parent
3339 -- type. In order to avoid creating redundant invariant checks, do
3340 -- not process the components now. Instead wait until the ultimate
3341 -- parent of the untagged derivation chain is reached.
3342
3343 if not Is_Untagged_Derivation (T) then
3344 Def := Type_Definition (Parent (T));
3345
3346 if Nkind (Def) = N_Derived_Type_Definition then
3347 Def := Record_Extension_Part (Def);
3348 end if;
3349
3350 pragma Assert (Nkind (Def) = N_Record_Definition);
3351 Comps := Component_List (Def);
3352
3353 if Present (Comps) then
3354 Process_Component_List
3355 (Comp_List => Comps,
3356 CL_Checks => Checks);
3357 end if;
3358 end if;
3359 end Add_Record_Component_Invariants;
3360
51148dda
AC
3361 -- Local variables
3362
9057bd6a
HK
3363 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
3364 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
3365 -- Save the Ghost-related attributes to restore on exit
f9a8f910 3366
ded462b0 3367 Dummy : Entity_Id;
51148dda
AC
3368 Priv_Item : Node_Id;
3369 Proc_Body : Node_Id;
3370 Proc_Body_Id : Entity_Id;
3371 Proc_Decl : Node_Id;
3372 Proc_Id : Entity_Id;
3373 Stmts : List_Id := No_List;
3374
b554177a 3375 CRec_Typ : Entity_Id := Empty;
51148dda
AC
3376 -- The corresponding record type of Full_Typ
3377
b554177a 3378 Full_Proc : Entity_Id := Empty;
51148dda
AC
3379 -- The entity of the "full" invariant procedure
3380
b554177a 3381 Full_Typ : Entity_Id := Empty;
51148dda
AC
3382 -- The full view of the working type
3383
b554177a 3384 Obj_Id : Entity_Id := Empty;
51148dda
AC
3385 -- The _object formal parameter of the invariant procedure
3386
b554177a 3387 Part_Proc : Entity_Id := Empty;
51148dda
AC
3388 -- The entity of the "partial" invariant procedure
3389
b554177a 3390 Priv_Typ : Entity_Id := Empty;
51148dda
AC
3391 -- The partial view of the working type
3392
b554177a 3393 Work_Typ : Entity_Id := Empty;
51148dda
AC
3394 -- The working type
3395
3396 -- Start of processing for Build_Invariant_Procedure_Body
3397
3398 begin
3399 Work_Typ := Typ;
3400
b97813ab
EB
3401 -- Do not process the underlying full view of a private type. There is
3402 -- no way to get back to the partial view, plus the body will be built
3403 -- by the full view or the base type.
3404
3405 if Is_Underlying_Full_View (Work_Typ) then
3406 return;
3407
51148dda
AC
3408 -- The input type denotes the implementation base type of a constrained
3409 -- array type. Work with the first subtype as all invariant pragmas are
3410 -- on its rep item chain.
3411
b97813ab 3412 elsif Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
51148dda
AC
3413 Work_Typ := First_Subtype (Work_Typ);
3414
3415 -- The input type denotes the corresponding record type of a protected
3416 -- or task type. Work with the concurrent type because the corresponding
3417 -- record type may not be visible to clients of the type.
3418
3419 elsif Ekind (Work_Typ) = E_Record_Type
3420 and then Is_Concurrent_Record_Type (Work_Typ)
3421 then
3422 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3423 end if;
3424
3425 -- The working type may be subject to pragma Ghost. Set the mode now to
3426 -- ensure that the invariant procedure is properly marked as Ghost.
3427
f9a8f910 3428 Set_Ghost_Mode (Work_Typ);
51148dda
AC
3429
3430 -- The type must either have invariants of its own, inherit class-wide
3431 -- invariants from parent types or interfaces, or be an array or record
3432 -- type whose components have invariants.
3433
3434 pragma Assert (Has_Invariants (Work_Typ));
3435
b554177a
AC
3436 -- Interfaces are treated as the partial view of a private type in order
3437 -- to achieve uniformity with the general case.
51148dda
AC
3438
3439 if Is_Interface (Work_Typ) then
b554177a 3440 Priv_Typ := Work_Typ;
51148dda 3441
b554177a 3442 -- Otherwise obtain both views of the type
51148dda 3443
b554177a
AC
3444 else
3445 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy, CRec_Typ);
3446 end if;
51148dda
AC
3447
3448 -- The caller requests a body for the partial invariant procedure
3449
3450 if Partial_Invariant then
3451 Full_Proc := Invariant_Procedure (Work_Typ);
3452 Proc_Id := Partial_Invariant_Procedure (Work_Typ);
3453
3454 -- The "full" invariant procedure body was already created
3455
3456 if Present (Full_Proc)
3457 and then Present
3458 (Corresponding_Body (Unit_Declaration_Node (Full_Proc)))
3459 then
3460 -- This scenario happens only when the type is an untagged
3461 -- derivation from a private parent and the underlying full
3462 -- view was processed before the partial view.
3463
3464 pragma Assert
3465 (Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ));
3466
3467 -- Nothing to do because the processing of the underlying full
3468 -- view already checked the invariants of the partial view.
3469
3470 goto Leave;
3471 end if;
3472
3473 -- Create a declaration for the "partial" invariant procedure if it
3474 -- is not available.
3475
3476 if No (Proc_Id) then
3477 Build_Invariant_Procedure_Declaration
3478 (Typ => Work_Typ,
3479 Partial_Invariant => True);
3480
3481 Proc_Id := Partial_Invariant_Procedure (Work_Typ);
3482 end if;
3483
3484 -- The caller requests a body for the "full" invariant procedure
3485
3486 else
3487 Proc_Id := Invariant_Procedure (Work_Typ);
3488 Part_Proc := Partial_Invariant_Procedure (Work_Typ);
3489
3490 -- Create a declaration for the "full" invariant procedure if it is
3491 -- not available.
3492
3493 if No (Proc_Id) then
3494 Build_Invariant_Procedure_Declaration (Work_Typ);
3495 Proc_Id := Invariant_Procedure (Work_Typ);
3496 end if;
3497 end if;
3498
3499 -- At this point there should be an invariant procedure declaration
3500
3501 pragma Assert (Present (Proc_Id));
3502 Proc_Decl := Unit_Declaration_Node (Proc_Id);
3503
3504 -- Nothing to do if the invariant procedure already has a body
3505
3506 if Present (Corresponding_Body (Proc_Decl)) then
3507 goto Leave;
3508 end if;
3509
b554177a
AC
3510 -- Emulate the environment of the invariant procedure by installing its
3511 -- scope and formal parameters. Note that this is not needed, but having
3512 -- the scope installed helps with the detection of invariant-related
3513 -- errors.
51148dda
AC
3514
3515 Push_Scope (Proc_Id);
3516 Install_Formals (Proc_Id);
3517
3518 Obj_Id := First_Formal (Proc_Id);
3519 pragma Assert (Present (Obj_Id));
3520
3521 -- The "partial" invariant procedure verifies the invariants of the
3522 -- partial view only.
3523
3524 if Partial_Invariant then
3525 pragma Assert (Present (Priv_Typ));
3526
003d46d5 3527 Add_Own_Invariants
998429d6
AC
3528 (T => Priv_Typ,
3529 Obj_Id => Obj_Id,
3530 Checks => Stmts);
51148dda
AC
3531
3532 -- Otherwise the "full" invariant procedure verifies the invariants of
3533 -- the full view, all array or record components, as well as class-wide
3534 -- invariants inherited from parent types or interfaces. In addition, it
3535 -- indirectly verifies the invariants of the partial view by calling the
3536 -- "partial" invariant procedure.
3537
3538 else
3539 pragma Assert (Present (Full_Typ));
3540
3541 -- Check the invariants of the partial view by calling the "partial"
3542 -- invariant procedure. Generate:
3543
3544 -- <Work_Typ>Partial_Invariant (_object);
3545
3546 if Present (Part_Proc) then
3547 Append_New_To (Stmts,
3548 Make_Procedure_Call_Statement (Loc,
3549 Name => New_Occurrence_Of (Part_Proc, Loc),
3550 Parameter_Associations => New_List (
3551 New_Occurrence_Of (Obj_Id, Loc))));
3552
3553 Produced_Check := True;
3554 end if;
3555
3556 Priv_Item := Empty;
3557
3558 -- Derived subtypes do not have a partial view
3559
3560 if Present (Priv_Typ) then
3561
3562 -- The processing of the "full" invariant procedure intentionally
3563 -- skips the partial view because a) this may result in changes of
3564 -- visibility and b) lead to duplicate checks. However, when the
3565 -- full view is the underlying full view of an untagged derived
3566 -- type whose parent type is private, partial invariants appear on
3567 -- the rep item chain of the partial view only.
3568
3569 -- package Pack_1 is
3570 -- type Root ... is private;
3571 -- private
3572 -- <full view of Root>
3573 -- end Pack_1;
3574
3575 -- with Pack_1;
3576 -- package Pack_2 is
3577 -- type Child is new Pack_1.Root with Type_Invariant => ...;
3578 -- <underlying full view of Child>
3579 -- end Pack_2;
3580
3581 -- As a result, the processing of the full view must also consider
3582 -- all invariants of the partial view.
3583
3584 if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then
3585 null;
3586
3587 -- Otherwise the invariants of the partial view are ignored
3588
3589 else
3590 -- Note that the rep item chain is shared between the partial
3591 -- and full views of a type. To avoid processing the invariants
3592 -- of the partial view, signal the logic to stop when the first
3593 -- rep item of the partial view has been reached.
3594
3595 Priv_Item := First_Rep_Item (Priv_Typ);
3596
3597 -- Ignore the invariants of the partial view by eliminating the
3598 -- view.
3599
3600 Priv_Typ := Empty;
3601 end if;
3602 end if;
3603
3604 -- Process the invariants of the full view and in certain cases those
3605 -- of the partial view. This also handles any invariants on array or
3606 -- record components.
3607
003d46d5 3608 Add_Own_Invariants
998429d6 3609 (T => Priv_Typ,
51148dda
AC
3610 Obj_Id => Obj_Id,
3611 Checks => Stmts,
3612 Priv_Item => Priv_Item);
3613
003d46d5 3614 Add_Own_Invariants
998429d6
AC
3615 (T => Full_Typ,
3616 Obj_Id => Obj_Id,
3617 Checks => Stmts,
3618 Priv_Item => Priv_Item);
3619
b554177a
AC
3620 -- Process the elements of an array type
3621
3622 if Is_Array_Type (Full_Typ) then
3623 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3624
3625 -- Process the components of a record type
3626
3627 elsif Ekind (Full_Typ) = E_Record_Type then
3628 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Stmts);
3629
3630 -- Process the components of a corresponding record
3631
3632 elsif Present (CRec_Typ) then
998429d6
AC
3633 Add_Record_Component_Invariants (CRec_Typ, Obj_Id, Stmts);
3634 end if;
3635
51148dda
AC
3636 -- Process the inherited class-wide invariants of all parent types.
3637 -- This also handles any invariants on record components.
3638
ded462b0 3639 Add_Parent_Invariants (Full_Typ, Obj_Id, Stmts);
998429d6 3640
ded462b0
AC
3641 -- Process the inherited class-wide invariants of all implemented
3642 -- interface types.
998429d6 3643
ded462b0 3644 Add_Interface_Invariants (Full_Typ, Obj_Id, Stmts);
51148dda
AC
3645 end if;
3646
3647 End_Scope;
3648
3649 -- At this point there should be at least one invariant check. If this
3650 -- is not the case, then the invariant-related flags were not properly
3651 -- set, or there is a missing invariant procedure on one of the array
3652 -- or record components.
3653
3654 pragma Assert (Produced_Check);
3655
3656 -- Account for the case where assertions are disabled or all invariant
3657 -- checks are subject to Assertion_Policy Ignore. Produce a completing
3658 -- empty body.
3659
3660 if No (Stmts) then
3661 Stmts := New_List (Make_Null_Statement (Loc));
3662 end if;
3663
3664 -- Generate:
b554177a 3665 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>) is
51148dda
AC
3666 -- begin
3667 -- <Stmts>
3668 -- end <Work_Typ>[Partial_]Invariant;
3669
3670 Proc_Body :=
3671 Make_Subprogram_Body (Loc,
3672 Specification =>
3673 Copy_Subprogram_Spec (Parent (Proc_Id)),
3674 Declarations => Empty_List,
3675 Handled_Statement_Sequence =>
3676 Make_Handled_Sequence_Of_Statements (Loc,
3677 Statements => Stmts));
3678 Proc_Body_Id := Defining_Entity (Proc_Body);
3679
3680 -- Perform minor decoration in case the body is not analyzed
3681
3682 Set_Ekind (Proc_Body_Id, E_Subprogram_Body);
3683 Set_Etype (Proc_Body_Id, Standard_Void_Type);
3684 Set_Scope (Proc_Body_Id, Current_Scope);
3685
3686 -- Link both spec and body to avoid generating duplicates
3687
3688 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id);
3689 Set_Corresponding_Spec (Proc_Body, Proc_Id);
3690
3691 -- The body should not be inserted into the tree when the context is
65f1ca2e 3692 -- a generic unit because it is not part of the template. Note
51148dda
AC
3693 -- that the body must still be generated in order to resolve the
3694 -- invariants.
3695
65f1ca2e 3696 if Inside_A_Generic then
51148dda
AC
3697 null;
3698
3699 -- Semi-insert the body into the tree for GNATprove by setting its
3700 -- Parent field. This allows for proper upstream tree traversals.
3701
3702 elsif GNATprove_Mode then
3703 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ)));
3704
3705 -- Otherwise the body is part of the freezing actions of the type
3706
3707 else
3708 Append_Freeze_Action (Work_Typ, Proc_Body);
3709 end if;
3710
3711 <<Leave>>
9057bd6a 3712 Restore_Ghost_Region (Saved_GM, Saved_IGR);
51148dda
AC
3713 end Build_Invariant_Procedure_Body;
3714
3715 -------------------------------------------
3716 -- Build_Invariant_Procedure_Declaration --
3717 -------------------------------------------
3718
3719 -- WARNING: This routine manages Ghost regions. Return statements must be
3720 -- replaced by gotos which jump to the end of the routine and restore the
3721 -- Ghost mode.
3722
3723 procedure Build_Invariant_Procedure_Declaration
3724 (Typ : Entity_Id;
3725 Partial_Invariant : Boolean := False)
3726 is
3727 Loc : constant Source_Ptr := Sloc (Typ);
3728
9057bd6a
HK
3729 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
3730 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
3731 -- Save the Ghost-related attributes to restore on exit
f9a8f910 3732
51148dda
AC
3733 Proc_Decl : Node_Id;
3734 Proc_Id : Entity_Id;
3735 Proc_Nam : Name_Id;
3736 Typ_Decl : Node_Id;
3737
3738 CRec_Typ : Entity_Id;
3739 -- The corresponding record type of Full_Typ
3740
51148dda
AC
3741 Full_Typ : Entity_Id;
3742 -- The full view of working type
3743
3744 Obj_Id : Entity_Id;
3745 -- The _object formal parameter of the invariant procedure
3746
b554177a
AC
3747 Obj_Typ : Entity_Id;
3748 -- The type of the _object formal parameter
3749
51148dda
AC
3750 Priv_Typ : Entity_Id;
3751 -- The partial view of working type
3752
b97813ab
EB
3753 UFull_Typ : Entity_Id;
3754 -- The underlying full view of Full_Typ
3755
51148dda
AC
3756 Work_Typ : Entity_Id;
3757 -- The working type
3758
3759 begin
3760 Work_Typ := Typ;
3761
3762 -- The input type denotes the implementation base type of a constrained
3763 -- array type. Work with the first subtype as all invariant pragmas are
3764 -- on its rep item chain.
3765
3766 if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then
3767 Work_Typ := First_Subtype (Work_Typ);
3768
3769 -- The input denotes the corresponding record type of a protected or a
3770 -- task type. Work with the concurrent type because the corresponding
3771 -- record type may not be visible to clients of the type.
3772
3773 elsif Ekind (Work_Typ) = E_Record_Type
3774 and then Is_Concurrent_Record_Type (Work_Typ)
3775 then
3776 Work_Typ := Corresponding_Concurrent_Type (Work_Typ);
3777 end if;
3778
3779 -- The working type may be subject to pragma Ghost. Set the mode now to
3780 -- ensure that the invariant procedure is properly marked as Ghost.
3781
f9a8f910 3782 Set_Ghost_Mode (Work_Typ);
51148dda
AC
3783
3784 -- The type must either have invariants of its own, inherit class-wide
3785 -- invariants from parent or interface types, or be an array or record
3786 -- type whose components have invariants.
3787
3788 pragma Assert (Has_Invariants (Work_Typ));
3789
51148dda
AC
3790 -- Nothing to do if the type already has a "partial" invariant procedure
3791
b554177a 3792 if Partial_Invariant then
51148dda
AC
3793 if Present (Partial_Invariant_Procedure (Work_Typ)) then
3794 goto Leave;
3795 end if;
3796
3797 -- Nothing to do if the type already has a "full" invariant procedure
3798
3799 elsif Present (Invariant_Procedure (Work_Typ)) then
3800 goto Leave;
3801 end if;
3802
3803 -- The caller requests the declaration of the "partial" invariant
3804 -- procedure.
3805
3806 if Partial_Invariant then
3807 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_Invariant");
3808
3809 -- Otherwise the caller requests the declaration of the "full" invariant
3810 -- procedure.
3811
3812 else
3813 Proc_Nam := New_External_Name (Chars (Work_Typ), "Invariant");
3814 end if;
3815
3816 Proc_Id := Make_Defining_Identifier (Loc, Chars => Proc_Nam);
3817
3818 -- Perform minor decoration in case the declaration is not analyzed
3819
3820 Set_Ekind (Proc_Id, E_Procedure);
3821 Set_Etype (Proc_Id, Standard_Void_Type);
3822 Set_Scope (Proc_Id, Current_Scope);
3823
3824 if Partial_Invariant then
3825 Set_Is_Partial_Invariant_Procedure (Proc_Id);
3826 Set_Partial_Invariant_Procedure (Work_Typ, Proc_Id);
3827 else
3828 Set_Is_Invariant_Procedure (Proc_Id);
3829 Set_Invariant_Procedure (Work_Typ, Proc_Id);
3830 end if;
3831
3832 -- The invariant procedure requires debug info when the invariants are
3833 -- subject to Source Coverage Obligations.
3834
90e491a7 3835 if Generate_SCO then
923ecd0e 3836 Set_Debug_Info_Needed (Proc_Id);
51148dda
AC
3837 end if;
3838
3839 -- Obtain all views of the input type
3840
b97813ab 3841 Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ);
51148dda 3842
b97813ab 3843 -- Associate the invariant procedure and various flags with all views
51148dda
AC
3844
3845 Propagate_Invariant_Attributes (Priv_Typ, From_Typ => Work_Typ);
3846 Propagate_Invariant_Attributes (Full_Typ, From_Typ => Work_Typ);
b97813ab 3847 Propagate_Invariant_Attributes (UFull_Typ, From_Typ => Work_Typ);
51148dda
AC
3848 Propagate_Invariant_Attributes (CRec_Typ, From_Typ => Work_Typ);
3849
3850 -- The declaration of the invariant procedure is inserted after the
3851 -- declaration of the partial view as this allows for proper external
3852 -- visibility.
3853
3854 if Present (Priv_Typ) then
3855 Typ_Decl := Declaration_Node (Priv_Typ);
3856
63a5b3dc
AC
3857 -- Anonymous arrays in object declarations have no explicit declaration
3858 -- so use the related object declaration as the insertion point.
3859
3860 elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then
3861 Typ_Decl := Associated_Node_For_Itype (Work_Typ);
51148dda 3862
4ac62786
AC
3863 -- Derived types with the full view as parent do not have a partial
3864 -- view. Insert the invariant procedure after the derived type.
3865
51148dda
AC
3866 else
3867 Typ_Decl := Declaration_Node (Full_Typ);
3868 end if;
3869
3870 -- The type should have a declarative node
3871
3872 pragma Assert (Present (Typ_Decl));
3873
3874 -- Create the formal parameter which emulates the variable-like behavior
3875 -- of the current type instance.
3876
3877 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject);
3878
b554177a
AC
3879 -- When generating an invariant procedure declaration for an abstract
3880 -- type (including interfaces), use the class-wide type as the _object
3881 -- type. This has several desirable effects:
3882
3883 -- * The invariant procedure does not become a primitive of the type.
3884 -- This eliminates the need to either special case the treatment of
3885 -- invariant procedures, or to make it a predefined primitive and
3886 -- force every derived type to potentially provide an empty body.
3887
3888 -- * The invariant procedure does not need to be declared as abstract.
ca0b6141 3889 -- This allows for a proper body, which in turn avoids redundant
b554177a
AC
3890 -- processing of the same invariants for types with multiple views.
3891
3892 -- * The class-wide type allows for calls to abstract primitives
ca0b6141 3893 -- within a nonabstract subprogram. The calls are treated as
b554177a
AC
3894 -- dispatching and require additional processing when they are
3895 -- remapped to call primitives of derived types. See routine
3896 -- Replace_References for details.
3897
3898 if Is_Abstract_Type (Work_Typ) then
3899 Obj_Typ := Class_Wide_Type (Work_Typ);
3900 else
3901 Obj_Typ := Work_Typ;
3902 end if;
3903
51148dda
AC
3904 -- Perform minor decoration in case the declaration is not analyzed
3905
3906 Set_Ekind (Obj_Id, E_In_Parameter);
b554177a 3907 Set_Etype (Obj_Id, Obj_Typ);
51148dda
AC
3908 Set_Scope (Obj_Id, Proc_Id);
3909
3910 Set_First_Entity (Proc_Id, Obj_Id);
51f3e4e1 3911 Set_Last_Entity (Proc_Id, Obj_Id);
51148dda
AC
3912
3913 -- Generate:
b554177a 3914 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>);
51148dda
AC
3915
3916 Proc_Decl :=
3917 Make_Subprogram_Declaration (Loc,
3918 Specification =>
3919 Make_Procedure_Specification (Loc,
3920 Defining_Unit_Name => Proc_Id,
3921 Parameter_Specifications => New_List (
3922 Make_Parameter_Specification (Loc,
3923 Defining_Identifier => Obj_Id,
b554177a 3924 Parameter_Type => New_Occurrence_Of (Obj_Typ, Loc)))));
51148dda
AC
3925
3926 -- The declaration should not be inserted into the tree when the context
65f1ca2e 3927 -- is a generic unit because it is not part of the template.
51148dda 3928
65f1ca2e 3929 if Inside_A_Generic then
51148dda
AC
3930 null;
3931
3932 -- Semi-insert the declaration into the tree for GNATprove by setting
3933 -- its Parent field. This allows for proper upstream tree traversals.
3934
3935 elsif GNATprove_Mode then
3936 Set_Parent (Proc_Decl, Parent (Typ_Decl));
3937
3938 -- Otherwise insert the declaration
3939
3940 else
3941 pragma Assert (Present (Typ_Decl));
3942 Insert_After_And_Analyze (Typ_Decl, Proc_Decl);
3943 end if;
3944
3945 <<Leave>>
9057bd6a 3946 Restore_Ghost_Region (Saved_GM, Saved_IGR);
51148dda
AC
3947 end Build_Invariant_Procedure_Declaration;
3948
51b42ffa
AC
3949 --------------------------
3950 -- Build_Procedure_Form --
3951 --------------------------
3952
3953 procedure Build_Procedure_Form (N : Node_Id) is
268aeaa9
AC
3954 Loc : constant Source_Ptr := Sloc (N);
3955 Subp : constant Entity_Id := Defining_Entity (N);
51b42ffa
AC
3956
3957 Func_Formal : Entity_Id;
3958 Proc_Formals : List_Id;
17fd72ce 3959 Proc_Decl : Node_Id;
51b42ffa
AC
3960
3961 begin
2a253c5b
AC
3962 -- No action needed if this transformation was already done, or in case
3963 -- of subprogram renaming declarations.
aeb98f1d 3964
a14bbbb4
AC
3965 if Nkind (Specification (N)) = N_Procedure_Specification
3966 or else Nkind (N) = N_Subprogram_Renaming_Declaration
3967 then
aeb98f1d
JM
3968 return;
3969 end if;
3970
2a253c5b
AC
3971 -- Ditto when dealing with an expression function, where both the
3972 -- original expression and the generated declaration end up being
3973 -- expanded here.
3974
3975 if Rewritten_For_C (Subp) then
3976 return;
3977 end if;
3978
51b42ffa
AC
3979 Proc_Formals := New_List;
3980
3981 -- Create a list of formal parameters with the same types as the
3982 -- function.
3983
3984 Func_Formal := First_Formal (Subp);
3985 while Present (Func_Formal) loop
3986 Append_To (Proc_Formals,
3987 Make_Parameter_Specification (Loc,
3988 Defining_Identifier =>
51b42ffa
AC
3989 Make_Defining_Identifier (Loc, Chars (Func_Formal)),
3990 Parameter_Type =>
3991 New_Occurrence_Of (Etype (Func_Formal), Loc)));
3992
3993 Next_Formal (Func_Formal);
3994 end loop;
3995
3996 -- Add an extra out parameter to carry the function result
3997
51b42ffa
AC
3998 Append_To (Proc_Formals,
3999 Make_Parameter_Specification (Loc,
4000 Defining_Identifier =>
b50706ef 4001 Make_Defining_Identifier (Loc, Name_UP_RESULT),
51b42ffa
AC
4002 Out_Present => True,
4003 Parameter_Type => New_Occurrence_Of (Etype (Subp), Loc)));
4004
d79e7af5
AC
4005 -- The new procedure declaration is inserted before the function
4006 -- declaration. The processing in Build_Procedure_Body_Form relies on
4007 -- this order. Note that we insert before because in the case of a
4008 -- function body with no separate spec, we do not want to insert the
4009 -- new spec after the body which will later get rewritten.
51b42ffa 4010
17fd72ce 4011 Proc_Decl :=
51b42ffa
AC
4012 Make_Subprogram_Declaration (Loc,
4013 Specification =>
4014 Make_Procedure_Specification (Loc,
4015 Defining_Unit_Name =>
4016 Make_Defining_Identifier (Loc, Chars (Subp)),
17fd72ce
ES
4017 Parameter_Specifications => Proc_Formals));
4018
d79e7af5 4019 Insert_Before_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl);
17fd72ce
ES
4020
4021 -- Entity of procedure must remain invisible so that it does not
4022 -- overload subsequent references to the original function.
4023
4024 Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False);
51b42ffa 4025
888be6b1
AC
4026 -- Mark the function as having a procedure form and link the function
4027 -- and its internally built procedure.
51b42ffa
AC
4028
4029 Set_Rewritten_For_C (Subp);
888be6b1
AC
4030 Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl));
4031 Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp);
51b42ffa
AC
4032 end Build_Procedure_Form;
4033
70482933
RK
4034 ------------------------
4035 -- Build_Runtime_Call --
4036 ------------------------
4037
4038 function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is
4039 begin
fbf5a39b
AC
4040 -- If entity is not available, we can skip making the call (this avoids
4041 -- junk duplicated error messages in a number of cases).
4042
4043 if not RTE_Available (RE) then
4044 return Make_Null_Statement (Loc);
4045 else
4046 return
4047 Make_Procedure_Call_Statement (Loc,
e4494292 4048 Name => New_Occurrence_Of (RTE (RE), Loc));
fbf5a39b 4049 end if;
70482933
RK
4050 end Build_Runtime_Call;
4051
8e888920
AC
4052 ------------------------
4053 -- Build_SS_Mark_Call --
4054 ------------------------
4055
4056 function Build_SS_Mark_Call
4057 (Loc : Source_Ptr;
4058 Mark : Entity_Id) return Node_Id
4059 is
4060 begin
4061 -- Generate:
4062 -- Mark : constant Mark_Id := SS_Mark;
4063
4064 return
4065 Make_Object_Declaration (Loc,
4066 Defining_Identifier => Mark,
4067 Constant_Present => True,
4068 Object_Definition =>
4069 New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
4070 Expression =>
4071 Make_Function_Call (Loc,
4072 Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc)));
4073 end Build_SS_Mark_Call;
4074
4075 ---------------------------
4076 -- Build_SS_Release_Call --
4077 ---------------------------
4078
4079 function Build_SS_Release_Call
4080 (Loc : Source_Ptr;
4081 Mark : Entity_Id) return Node_Id
4082 is
4083 begin
4084 -- Generate:
4085 -- SS_Release (Mark);
4086
4087 return
4088 Make_Procedure_Call_Statement (Loc,
4089 Name =>
4090 New_Occurrence_Of (RTE (RE_SS_Release), Loc),
4091 Parameter_Associations => New_List (
4092 New_Occurrence_Of (Mark, Loc)));
4093 end Build_SS_Release_Call;
4094
15ce9ca2
AC
4095 ----------------------------
4096 -- Build_Task_Array_Image --
4097 ----------------------------
70482933
RK
4098
4099 -- This function generates the body for a function that constructs the
4100 -- image string for a task that is an array component. The function is
fbf5a39b 4101 -- local to the init proc for the array type, and is called for each one
70482933
RK
4102 -- of the components. The constructed image has the form of an indexed
4103 -- component, whose prefix is the outer variable of the array type.
3b42c566 4104 -- The n-dimensional array type has known indexes Index, Index2...
273adcdf 4105
fbf5a39b 4106 -- Id_Ref is an indexed component form created by the enclosing init proc.
3b42c566 4107 -- Its successive indexes are Val1, Val2, ... which are the loop variables
fbf5a39b 4108 -- in the loops that call the individual task init proc on each component.
70482933
RK
4109
4110 -- The generated function has the following structure:
4111
fbf5a39b
AC
4112 -- function F return String is
4113 -- Pref : string renames Task_Name;
4114 -- T1 : String := Index1'Image (Val1);
70482933 4115 -- ...
fbf5a39b
AC
4116 -- Tn : String := indexn'image (Valn);
4117 -- Len : Integer := T1'Length + ... + Tn'Length + n + 1;
70482933 4118 -- -- Len includes commas and the end parentheses.
fbf5a39b
AC
4119 -- Res : String (1..Len);
4120 -- Pos : Integer := Pref'Length;
70482933
RK
4121 --
4122 -- begin
7bc1c7df 4123 -- Res (1 .. Pos) := Pref;
70482933
RK
4124 -- Pos := Pos + 1;
4125 -- Res (Pos) := '(';
4126 -- Pos := Pos + 1;
4127 -- Res (Pos .. Pos + T1'Length - 1) := T1;
4128 -- Pos := Pos + T1'Length;
4129 -- Res (Pos) := '.';
4130 -- Pos := Pos + 1;
4131 -- ...
4132 -- Res (Pos .. Pos + Tn'Length - 1) := Tn;
4133 -- Res (Len) := ')';
4134 --
fbf5a39b 4135 -- return Res;
70482933
RK
4136 -- end F;
4137 --
273adcdf
AC
4138 -- Needless to say, multidimensional arrays of tasks are rare enough that
4139 -- the bulkiness of this code is not really a concern.
70482933
RK
4140
4141 function Build_Task_Array_Image
4142 (Loc : Source_Ptr;
4143 Id_Ref : Node_Id;
7bc1c7df 4144 A_Type : Entity_Id;
bebbff91 4145 Dyn : Boolean := False) return Node_Id
70482933
RK
4146 is
4147 Dims : constant Nat := Number_Dimensions (A_Type);
bebbff91 4148 -- Number of dimensions for array of tasks
70482933
RK
4149
4150 Temps : array (1 .. Dims) of Entity_Id;
bebbff91 4151 -- Array of temporaries to hold string for each index
70482933
RK
4152
4153 Indx : Node_Id;
4154 -- Index expression
4155
4156 Len : Entity_Id;
4157 -- Total length of generated name
4158
4159 Pos : Entity_Id;
4160 -- Running index for substring assignments
4161
092ef350 4162 Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
70482933
RK
4163 -- Name of enclosing variable, prefix of resulting name
4164
4165 Res : Entity_Id;
4166 -- String to hold result
4167
4168 Val : Node_Id;
3b42c566 4169 -- Value of successive indexes
70482933
RK
4170
4171 Sum : Node_Id;
4172 -- Expression to compute total size of string
4173
4174 T : Entity_Id;
4175 -- Entity for name at one index position
4176
86cde7b1
RD
4177 Decls : constant List_Id := New_List;
4178 Stats : constant List_Id := New_List;
70482933
RK
4179
4180 begin
273adcdf
AC
4181 -- For a dynamic task, the name comes from the target variable. For a
4182 -- static one it is a formal of the enclosing init proc.
7bc1c7df
ES
4183
4184 if Dyn then
4185 Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
fbf5a39b
AC
4186 Append_To (Decls,
4187 Make_Object_Declaration (Loc,
4188 Defining_Identifier => Pref,
4189 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4190 Expression =>
bebbff91
AC
4191 Make_String_Literal (Loc,
4192 Strval => String_From_Name_Buffer)));
fbf5a39b 4193
7bc1c7df 4194 else
fbf5a39b
AC
4195 Append_To (Decls,
4196 Make_Object_Renaming_Declaration (Loc,
4197 Defining_Identifier => Pref,
4198 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4199 Name => Make_Identifier (Loc, Name_uTask_Name)));
7bc1c7df 4200 end if;
70482933 4201
70482933
RK
4202 Indx := First_Index (A_Type);
4203 Val := First (Expressions (Id_Ref));
4204
4205 for J in 1 .. Dims loop
092ef350 4206 T := Make_Temporary (Loc, 'T');
70482933
RK
4207 Temps (J) := T;
4208
4209 Append_To (Decls,
18a2ad5d
AC
4210 Make_Object_Declaration (Loc,
4211 Defining_Identifier => T,
4212 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4213 Expression =>
4214 Make_Attribute_Reference (Loc,
4215 Attribute_Name => Name_Image,
4216 Prefix => New_Occurrence_Of (Etype (Indx), Loc),
4217 Expressions => New_List (New_Copy_Tree (Val)))));
70482933
RK
4218
4219 Next_Index (Indx);
4220 Next (Val);
4221 end loop;
4222
4223 Sum := Make_Integer_Literal (Loc, Dims + 1);
4224
4225 Sum :=
4226 Make_Op_Add (Loc,
4227 Left_Opnd => Sum,
4228 Right_Opnd =>
18a2ad5d
AC
4229 Make_Attribute_Reference (Loc,
4230 Attribute_Name => Name_Length,
4231 Prefix => New_Occurrence_Of (Pref, Loc),
4232 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
70482933
RK
4233
4234 for J in 1 .. Dims loop
4235 Sum :=
18a2ad5d
AC
4236 Make_Op_Add (Loc,
4237 Left_Opnd => Sum,
70482933 4238 Right_Opnd =>
18a2ad5d
AC
4239 Make_Attribute_Reference (Loc,
4240 Attribute_Name => Name_Length,
4241 Prefix =>
70482933 4242 New_Occurrence_Of (Temps (J), Loc),
18a2ad5d 4243 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
70482933
RK
4244 end loop;
4245
7bc1c7df 4246 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
70482933
RK
4247
4248 Set_Character_Literal_Name (Char_Code (Character'Pos ('(')));
4249
4250 Append_To (Stats,
18a2ad5d
AC
4251 Make_Assignment_Statement (Loc,
4252 Name =>
4253 Make_Indexed_Component (Loc,
4254 Prefix => New_Occurrence_Of (Res, Loc),
70482933 4255 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
18a2ad5d
AC
4256 Expression =>
4257 Make_Character_Literal (Loc,
4258 Chars => Name_Find,
4259 Char_Literal_Value => UI_From_Int (Character'Pos ('(')))));
70482933
RK
4260
4261 Append_To (Stats,
18a2ad5d
AC
4262 Make_Assignment_Statement (Loc,
4263 Name => New_Occurrence_Of (Pos, Loc),
4264 Expression =>
4265 Make_Op_Add (Loc,
4266 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4267 Right_Opnd => Make_Integer_Literal (Loc, 1))));
70482933
RK
4268
4269 for J in 1 .. Dims loop
4270
4271 Append_To (Stats,
18a2ad5d
AC
4272 Make_Assignment_Statement (Loc,
4273 Name =>
4274 Make_Slice (Loc,
4275 Prefix => New_Occurrence_Of (Res, Loc),
70482933
RK
4276 Discrete_Range =>
4277 Make_Range (Loc,
18a2ad5d
AC
4278 Low_Bound => New_Occurrence_Of (Pos, Loc),
4279 High_Bound =>
4280 Make_Op_Subtract (Loc,
4281 Left_Opnd =>
4282 Make_Op_Add (Loc,
4283 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4284 Right_Opnd =>
4285 Make_Attribute_Reference (Loc,
4286 Attribute_Name => Name_Length,
4287 Prefix =>
4288 New_Occurrence_Of (Temps (J), Loc),
4289 Expressions =>
4290 New_List (Make_Integer_Literal (Loc, 1)))),
70482933
RK
4291 Right_Opnd => Make_Integer_Literal (Loc, 1)))),
4292
4293 Expression => New_Occurrence_Of (Temps (J), Loc)));
4294
4295 if J < Dims then
4296 Append_To (Stats,
4297 Make_Assignment_Statement (Loc,
18a2ad5d 4298 Name => New_Occurrence_Of (Pos, Loc),
70482933
RK
4299 Expression =>
4300 Make_Op_Add (Loc,
18a2ad5d 4301 Left_Opnd => New_Occurrence_Of (Pos, Loc),
70482933
RK
4302 Right_Opnd =>
4303 Make_Attribute_Reference (Loc,
4304 Attribute_Name => Name_Length,
18a2ad5d
AC
4305 Prefix => New_Occurrence_Of (Temps (J), Loc),
4306 Expressions =>
4307 New_List (Make_Integer_Literal (Loc, 1))))));
70482933
RK
4308
4309 Set_Character_Literal_Name (Char_Code (Character'Pos (',')));
4310
4311 Append_To (Stats,
18a2ad5d
AC
4312 Make_Assignment_Statement (Loc,
4313 Name => Make_Indexed_Component (Loc,
4314 Prefix => New_Occurrence_Of (Res, Loc),
4315 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4316 Expression =>
4317 Make_Character_Literal (Loc,
4318 Chars => Name_Find,
4319 Char_Literal_Value => UI_From_Int (Character'Pos (',')))));
70482933
RK
4320
4321 Append_To (Stats,
4322 Make_Assignment_Statement (Loc,
18a2ad5d 4323 Name => New_Occurrence_Of (Pos, Loc),
70482933
RK
4324 Expression =>
4325 Make_Op_Add (Loc,
18a2ad5d 4326 Left_Opnd => New_Occurrence_Of (Pos, Loc),
70482933
RK
4327 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4328 end if;
4329 end loop;
4330
4331 Set_Character_Literal_Name (Char_Code (Character'Pos (')')));
4332
4333 Append_To (Stats,
18a2ad5d
AC
4334 Make_Assignment_Statement (Loc,
4335 Name =>
4336 Make_Indexed_Component (Loc,
4337 Prefix => New_Occurrence_Of (Res, Loc),
70482933
RK
4338 Expressions => New_List (New_Occurrence_Of (Len, Loc))),
4339 Expression =>
4340 Make_Character_Literal (Loc,
18a2ad5d
AC
4341 Chars => Name_Find,
4342 Char_Literal_Value => UI_From_Int (Character'Pos (')')))));
70482933
RK
4343 return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4344 end Build_Task_Array_Image;
4345
4346 ----------------------------
4347 -- Build_Task_Image_Decls --
4348 ----------------------------
4349
4350 function Build_Task_Image_Decls
05350ac6
BD
4351 (Loc : Source_Ptr;
4352 Id_Ref : Node_Id;
4353 A_Type : Entity_Id;
4354 In_Init_Proc : Boolean := False) return List_Id
70482933 4355 is
fbf5a39b 4356 Decls : constant List_Id := New_List;
7bc1c7df
ES
4357 T_Id : Entity_Id := Empty;
4358 Decl : Node_Id;
7bc1c7df
ES
4359 Expr : Node_Id := Empty;
4360 Fun : Node_Id := Empty;
4361 Is_Dyn : constant Boolean :=
fbf5a39b
AC
4362 Nkind (Parent (Id_Ref)) = N_Assignment_Statement
4363 and then
4364 Nkind (Expression (Parent (Id_Ref))) = N_Allocator;
70482933
RK
4365
4366 begin
fbf5a39b
AC
4367 -- If Discard_Names or No_Implicit_Heap_Allocations are in effect,
4368 -- generate a dummy declaration only.
70482933 4369
6e937c1c 4370 if Restriction_Active (No_Implicit_Heap_Allocations)
fbf5a39b
AC
4371 or else Global_Discard_Names
4372 then
092ef350 4373 T_Id := Make_Temporary (Loc, 'J');
fbf5a39b 4374 Name_Len := 0;
70482933
RK
4375
4376 return
4377 New_List (
4378 Make_Object_Declaration (Loc,
4379 Defining_Identifier => T_Id,
fbf5a39b
AC
4380 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4381 Expression =>
bebbff91
AC
4382 Make_String_Literal (Loc,
4383 Strval => String_From_Name_Buffer)));
70482933
RK
4384
4385 else
4386 if Nkind (Id_Ref) = N_Identifier
4387 or else Nkind (Id_Ref) = N_Defining_Identifier
4388 then
523456db 4389 -- For a simple variable, the image of the task is built from
273adcdf
AC
4390 -- the name of the variable. To avoid possible conflict with the
4391 -- anonymous type created for a single protected object, add a
4392 -- numeric suffix.
70482933
RK
4393
4394 T_Id :=
4395 Make_Defining_Identifier (Loc,
523456db 4396 New_External_Name (Chars (Id_Ref), 'T', 1));
70482933
RK
4397
4398 Get_Name_String (Chars (Id_Ref));
4399
bebbff91
AC
4400 Expr :=
4401 Make_String_Literal (Loc,
4402 Strval => String_From_Name_Buffer);
70482933
RK
4403
4404 elsif Nkind (Id_Ref) = N_Selected_Component then
4405 T_Id :=
4406 Make_Defining_Identifier (Loc,
fbf5a39b 4407 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T'));
07fc65c4 4408 Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn);
70482933
RK
4409
4410 elsif Nkind (Id_Ref) = N_Indexed_Component then
4411 T_Id :=
4412 Make_Defining_Identifier (Loc,
fbf5a39b 4413 New_External_Name (Chars (A_Type), 'N'));
70482933 4414
7bc1c7df 4415 Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn);
70482933
RK
4416 end if;
4417 end if;
4418
4419 if Present (Fun) then
4420 Append (Fun, Decls);
fbf5a39b
AC
4421 Expr := Make_Function_Call (Loc,
4422 Name => New_Occurrence_Of (Defining_Entity (Fun), Loc));
05350ac6 4423
535a8637 4424 if not In_Init_Proc then
05350ac6
BD
4425 Set_Uses_Sec_Stack (Defining_Entity (Fun));
4426 end if;
70482933
RK
4427 end if;
4428
4429 Decl := Make_Object_Declaration (Loc,
4430 Defining_Identifier => T_Id,
fbf5a39b
AC
4431 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4432 Constant_Present => True,
4433 Expression => Expr);
70482933
RK
4434
4435 Append (Decl, Decls);
4436 return Decls;
4437 end Build_Task_Image_Decls;
4438
4439 -------------------------------
4440 -- Build_Task_Image_Function --
4441 -------------------------------
4442
4443 function Build_Task_Image_Function
4444 (Loc : Source_Ptr;
4445 Decls : List_Id;
4446 Stats : List_Id;
bebbff91 4447 Res : Entity_Id) return Node_Id
70482933
RK
4448 is
4449 Spec : Node_Id;
4450
4451 begin
4452 Append_To (Stats,
86cde7b1 4453 Make_Simple_Return_Statement (Loc,
fbf5a39b
AC
4454 Expression => New_Occurrence_Of (Res, Loc)));
4455
4456 Spec := Make_Function_Specification (Loc,
092ef350
RD
4457 Defining_Unit_Name => Make_Temporary (Loc, 'F'),
4458 Result_Definition => New_Occurrence_Of (Standard_String, Loc));
fbf5a39b 4459
273adcdf
AC
4460 -- Calls to 'Image use the secondary stack, which must be cleaned up
4461 -- after the task name is built.
fbf5a39b 4462
70482933
RK
4463 return Make_Subprogram_Body (Loc,
4464 Specification => Spec,
4465 Declarations => Decls,
4466 Handled_Statement_Sequence =>
fbf5a39b 4467 Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats));
70482933
RK
4468 end Build_Task_Image_Function;
4469
4470 -----------------------------
4471 -- Build_Task_Image_Prefix --
4472 -----------------------------
4473
4474 procedure Build_Task_Image_Prefix
4475 (Loc : Source_Ptr;
4476 Len : out Entity_Id;
4477 Res : out Entity_Id;
4478 Pos : out Entity_Id;
4479 Prefix : Entity_Id;
4480 Sum : Node_Id;
86cde7b1
RD
4481 Decls : List_Id;
4482 Stats : List_Id)
70482933
RK
4483 is
4484 begin
092ef350 4485 Len := Make_Temporary (Loc, 'L', Sum);
70482933
RK
4486
4487 Append_To (Decls,
4488 Make_Object_Declaration (Loc,
4489 Defining_Identifier => Len,
092ef350
RD
4490 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
4491 Expression => Sum));
70482933 4492
092ef350 4493 Res := Make_Temporary (Loc, 'R');
70482933
RK
4494
4495 Append_To (Decls,
4496 Make_Object_Declaration (Loc,
4497 Defining_Identifier => Res,
4498 Object_Definition =>
4499 Make_Subtype_Indication (Loc,
4500 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4501 Constraint =>
4502 Make_Index_Or_Discriminant_Constraint (Loc,
4503 Constraints =>
4504 New_List (
4505 Make_Range (Loc,
4506 Low_Bound => Make_Integer_Literal (Loc, 1),
4507 High_Bound => New_Occurrence_Of (Len, Loc)))))));
4508
f90d14ac
AC
4509 -- Indicate that the result is an internal temporary, so it does not
4510 -- receive a bogus initialization when declaration is expanded. This
4511 -- is both efficient, and prevents anomalies in the handling of
4512 -- dynamic objects on the secondary stack.
4513
4514 Set_Is_Internal (Res);
092ef350 4515 Pos := Make_Temporary (Loc, 'P');
70482933
RK
4516
4517 Append_To (Decls,
4518 Make_Object_Declaration (Loc,
4519 Defining_Identifier => Pos,
092ef350 4520 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc)));
70482933
RK
4521
4522 -- Pos := Prefix'Length;
4523
4524 Append_To (Stats,
4525 Make_Assignment_Statement (Loc,
4526 Name => New_Occurrence_Of (Pos, Loc),
4527 Expression =>
4528 Make_Attribute_Reference (Loc,
4529 Attribute_Name => Name_Length,
092ef350
RD
4530 Prefix => New_Occurrence_Of (Prefix, Loc),
4531 Expressions => New_List (Make_Integer_Literal (Loc, 1)))));
70482933
RK
4532
4533 -- Res (1 .. Pos) := Prefix;
4534
4535 Append_To (Stats,
092ef350
RD
4536 Make_Assignment_Statement (Loc,
4537 Name =>
4538 Make_Slice (Loc,
4539 Prefix => New_Occurrence_Of (Res, Loc),
70482933
RK
4540 Discrete_Range =>
4541 Make_Range (Loc,
092ef350 4542 Low_Bound => Make_Integer_Literal (Loc, 1),
70482933
RK
4543 High_Bound => New_Occurrence_Of (Pos, Loc))),
4544
092ef350 4545 Expression => New_Occurrence_Of (Prefix, Loc)));
70482933
RK
4546
4547 Append_To (Stats,
4548 Make_Assignment_Statement (Loc,
092ef350 4549 Name => New_Occurrence_Of (Pos, Loc),
70482933
RK
4550 Expression =>
4551 Make_Op_Add (Loc,
092ef350 4552 Left_Opnd => New_Occurrence_Of (Pos, Loc),
70482933
RK
4553 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4554 end Build_Task_Image_Prefix;
4555
4556 -----------------------------
4557 -- Build_Task_Record_Image --
4558 -----------------------------
4559
4560 function Build_Task_Record_Image
4561 (Loc : Source_Ptr;
4562 Id_Ref : Node_Id;
bebbff91 4563 Dyn : Boolean := False) return Node_Id
70482933
RK
4564 is
4565 Len : Entity_Id;
4566 -- Total length of generated name
4567
4568 Pos : Entity_Id;
4569 -- Index into result
4570
4571 Res : Entity_Id;
4572 -- String to hold result
4573
092ef350 4574 Pref : constant Entity_Id := Make_Temporary (Loc, 'P');
70482933
RK
4575 -- Name of enclosing variable, prefix of resulting name
4576
4577 Sum : Node_Id;
bebbff91 4578 -- Expression to compute total size of string
70482933
RK
4579
4580 Sel : Entity_Id;
4581 -- Entity for selector name
4582
86cde7b1
RD
4583 Decls : constant List_Id := New_List;
4584 Stats : constant List_Id := New_List;
70482933
RK
4585
4586 begin
aa9a7dd7
AC
4587 -- For a dynamic task, the name comes from the target variable. For a
4588 -- static one it is a formal of the enclosing init proc.
7bc1c7df
ES
4589
4590 if Dyn then
4591 Get_Name_String (Chars (Entity (Prefix (Id_Ref))));
fbf5a39b
AC
4592 Append_To (Decls,
4593 Make_Object_Declaration (Loc,
4594 Defining_Identifier => Pref,
4595 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4596 Expression =>
bebbff91
AC
4597 Make_String_Literal (Loc,
4598 Strval => String_From_Name_Buffer)));
fbf5a39b 4599
7bc1c7df 4600 else
fbf5a39b
AC
4601 Append_To (Decls,
4602 Make_Object_Renaming_Declaration (Loc,
4603 Defining_Identifier => Pref,
4604 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc),
4605 Name => Make_Identifier (Loc, Name_uTask_Name)));
7bc1c7df 4606 end if;
70482933 4607
092ef350 4608 Sel := Make_Temporary (Loc, 'S');
70482933
RK
4609
4610 Get_Name_String (Chars (Selector_Name (Id_Ref)));
4611
4612 Append_To (Decls,
4613 Make_Object_Declaration (Loc,
4614 Defining_Identifier => Sel,
092ef350
RD
4615 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
4616 Expression =>
bebbff91
AC
4617 Make_String_Literal (Loc,
4618 Strval => String_From_Name_Buffer)));
70482933
RK
4619
4620 Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1));
4621
4622 Sum :=
4623 Make_Op_Add (Loc,
4624 Left_Opnd => Sum,
4625 Right_Opnd =>
4626 Make_Attribute_Reference (Loc,
4627 Attribute_Name => Name_Length,
4628 Prefix =>
7bc1c7df 4629 New_Occurrence_Of (Pref, Loc),
70482933
RK
4630 Expressions => New_List (Make_Integer_Literal (Loc, 1))));
4631
7bc1c7df 4632 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats);
70482933
RK
4633
4634 Set_Character_Literal_Name (Char_Code (Character'Pos ('.')));
4635
4636 -- Res (Pos) := '.';
4637
4638 Append_To (Stats,
4639 Make_Assignment_Statement (Loc,
4640 Name => Make_Indexed_Component (Loc,
4641 Prefix => New_Occurrence_Of (Res, Loc),
4642 Expressions => New_List (New_Occurrence_Of (Pos, Loc))),
4643 Expression =>
4644 Make_Character_Literal (Loc,
4645 Chars => Name_Find,
4646 Char_Literal_Value =>
82c80734 4647 UI_From_Int (Character'Pos ('.')))));
70482933
RK
4648
4649 Append_To (Stats,
4650 Make_Assignment_Statement (Loc,
4651 Name => New_Occurrence_Of (Pos, Loc),
4652 Expression =>
4653 Make_Op_Add (Loc,
4654 Left_Opnd => New_Occurrence_Of (Pos, Loc),
4655 Right_Opnd => Make_Integer_Literal (Loc, 1))));
4656
4657 -- Res (Pos .. Len) := Selector;
4658
4659 Append_To (Stats,
4660 Make_Assignment_Statement (Loc,
4661 Name => Make_Slice (Loc,
4662 Prefix => New_Occurrence_Of (Res, Loc),
4663 Discrete_Range =>
4664 Make_Range (Loc,
4665 Low_Bound => New_Occurrence_Of (Pos, Loc),
4666 High_Bound => New_Occurrence_Of (Len, Loc))),
4667 Expression => New_Occurrence_Of (Sel, Loc)));
4668
4669 return Build_Task_Image_Function (Loc, Decls, Stats, Res);
4670 end Build_Task_Record_Image;
4671
937e9676
AC
4672 ---------------------------------------
4673 -- Build_Transient_Object_Statements --
4674 ---------------------------------------
4675
4676 procedure Build_Transient_Object_Statements
4677 (Obj_Decl : Node_Id;
4678 Fin_Call : out Node_Id;
4679 Hook_Assign : out Node_Id;
4680 Hook_Clear : out Node_Id;
4681 Hook_Decl : out Node_Id;
4682 Ptr_Decl : out Node_Id;
4683 Finalize_Obj : Boolean := True)
4684 is
4685 Loc : constant Source_Ptr := Sloc (Obj_Decl);
4686 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl);
4687 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
4688
4689 Desig_Typ : Entity_Id;
4690 Hook_Expr : Node_Id;
4691 Hook_Id : Entity_Id;
4692 Obj_Ref : Node_Id;
4693 Ptr_Typ : Entity_Id;
4694
4695 begin
4696 -- Recover the type of the object
4697
4698 Desig_Typ := Obj_Typ;
4699
4700 if Is_Access_Type (Desig_Typ) then
4701 Desig_Typ := Available_View (Designated_Type (Desig_Typ));
4702 end if;
4703
4704 -- Create an access type which provides a reference to the transient
4705 -- object. Generate:
4706
4707 -- type Ptr_Typ is access all Desig_Typ;
4708
4709 Ptr_Typ := Make_Temporary (Loc, 'A');
4710 Set_Ekind (Ptr_Typ, E_General_Access_Type);
4711 Set_Directly_Designated_Type (Ptr_Typ, Desig_Typ);
4712
4713 Ptr_Decl :=
4714 Make_Full_Type_Declaration (Loc,
4715 Defining_Identifier => Ptr_Typ,
4716 Type_Definition =>
4717 Make_Access_To_Object_Definition (Loc,
4718 All_Present => True,
4719 Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc)));
4720
4721 -- Create a temporary check which acts as a hook to the transient
4722 -- object. Generate:
4723
4724 -- Hook : Ptr_Typ := null;
4725
4726 Hook_Id := Make_Temporary (Loc, 'T');
4727 Set_Ekind (Hook_Id, E_Variable);
4728 Set_Etype (Hook_Id, Ptr_Typ);
4729
4730 Hook_Decl :=
4731 Make_Object_Declaration (Loc,
4732 Defining_Identifier => Hook_Id,
4733 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc),
4734 Expression => Make_Null (Loc));
4735
4736 -- Mark the temporary as a hook. This signals the machinery in
4737 -- Build_Finalizer to recognize this special case.
4738
4739 Set_Status_Flag_Or_Transient_Decl (Hook_Id, Obj_Decl);
4740
4741 -- Hook the transient object to the temporary. Generate:
4742
4743 -- Hook := Ptr_Typ (Obj_Id);
4744 -- <or>
4745 -- Hool := Obj_Id'Unrestricted_Access;
4746
4747 if Is_Access_Type (Obj_Typ) then
4748 Hook_Expr :=
4749 Unchecked_Convert_To (Ptr_Typ, New_Occurrence_Of (Obj_Id, Loc));
4750 else
4751 Hook_Expr :=
4752 Make_Attribute_Reference (Loc,
4753 Prefix => New_Occurrence_Of (Obj_Id, Loc),
4754 Attribute_Name => Name_Unrestricted_Access);
4755 end if;
4756
4757 Hook_Assign :=
4758 Make_Assignment_Statement (Loc,
4759 Name => New_Occurrence_Of (Hook_Id, Loc),
4760 Expression => Hook_Expr);
4761
4762 -- Crear the hook prior to finalizing the object. Generate:
4763
4764 -- Hook := null;
4765
4766 Hook_Clear :=
4767 Make_Assignment_Statement (Loc,
4768 Name => New_Occurrence_Of (Hook_Id, Loc),
4769 Expression => Make_Null (Loc));
4770
4771 -- Finalize the object. Generate:
4772
4773 -- [Deep_]Finalize (Obj_Ref[.all]);
4774
4775 if Finalize_Obj then
4776 Obj_Ref := New_Occurrence_Of (Obj_Id, Loc);
4777
4778 if Is_Access_Type (Obj_Typ) then
4779 Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref);
4780 Set_Etype (Obj_Ref, Desig_Typ);
4781 end if;
4782
2168d7cc
AC
4783 Fin_Call :=
4784 Make_Final_Call
4785 (Obj_Ref => Obj_Ref,
4786 Typ => Desig_Typ);
937e9676
AC
4787
4788 -- Otherwise finalize the hook. Generate:
4789
4790 -- [Deep_]Finalize (Hook.all);
4791
4792 else
4793 Fin_Call :=
4794 Make_Final_Call (
4795 Obj_Ref =>
4796 Make_Explicit_Dereference (Loc,
4797 Prefix => New_Occurrence_Of (Hook_Id, Loc)),
4798 Typ => Desig_Typ);
4799 end if;
4800 end Build_Transient_Object_Statements;
4801
d26d790d
AC
4802 -----------------------------
4803 -- Check_Float_Op_Overflow --
4804 -----------------------------
4805
4806 procedure Check_Float_Op_Overflow (N : Node_Id) is
4807 begin
4808 -- Return if no check needed
4809
bb304287
AC
4810 if not Is_Floating_Point_Type (Etype (N))
4811 or else not (Do_Overflow_Check (N) and then Check_Float_Overflow)
d26d790d 4812
af6478c8 4813 -- In CodePeer_Mode, rely on the overflow check flag being set instead
bb304287 4814 -- and do not expand the code for float overflow checking.
e943fe8a 4815
af6478c8
AC
4816 or else CodePeer_Mode
4817 then
4818 return;
e943fe8a
AC
4819 end if;
4820
d26d790d
AC
4821 -- Otherwise we replace the expression by
4822
4823 -- do Tnn : constant ftype := expression;
4824 -- constraint_error when not Tnn'Valid;
4825 -- in Tnn;
4826
4827 declare
4828 Loc : constant Source_Ptr := Sloc (N);
4829 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
4830 Typ : constant Entity_Id := Etype (N);
4831
4832 begin
bb304287
AC
4833 -- Turn off the Do_Overflow_Check flag, since we are doing that work
4834 -- right here. We also set the node as analyzed to prevent infinite
4835 -- recursion from repeating the operation in the expansion.
d26d790d 4836
bb304287
AC
4837 Set_Do_Overflow_Check (N, False);
4838 Set_Analyzed (N, True);
d26d790d
AC
4839
4840 -- Do the rewrite to include the check
4841
4842 Rewrite (N,
4843 Make_Expression_With_Actions (Loc,
4844 Actions => New_List (
4845 Make_Object_Declaration (Loc,
4846 Defining_Identifier => Tnn,
4847 Object_Definition => New_Occurrence_Of (Typ, Loc),
4848 Constant_Present => True,
4849 Expression => Relocate_Node (N)),
4850 Make_Raise_Constraint_Error (Loc,
4851 Condition =>
4852 Make_Op_Not (Loc,
4853 Right_Opnd =>
4854 Make_Attribute_Reference (Loc,
4855 Prefix => New_Occurrence_Of (Tnn, Loc),
4856 Attribute_Name => Name_Valid)),
4857 Reason => CE_Overflow_Check_Failed)),
4858 Expression => New_Occurrence_Of (Tnn, Loc)));
4859
4860 Analyze_And_Resolve (N, Typ);
4861 end;
4862 end Check_Float_Op_Overflow;
4863
91b1417d
AC
4864 ----------------------------------
4865 -- Component_May_Be_Bit_Aligned --
4866 ----------------------------------
4867
4868 function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
c97c0163 4869 UT : Entity_Id;
6fb4cdde 4870
91b1417d 4871 begin
dc7c0c4d 4872 -- If no component clause, then everything is fine, since the back end
fba9fcae
EB
4873 -- never misaligns from byte boundaries by default, even if there is a
4874 -- pragma Pack for the record.
91b1417d 4875
c97c0163 4876 if No (Comp) or else No (Component_Clause (Comp)) then
91b1417d
AC
4877 return False;
4878 end if;
4879
c97c0163
AC
4880 UT := Underlying_Type (Etype (Comp));
4881
91b1417d
AC
4882 -- It is only array and record types that cause trouble
4883
0e564ab4 4884 if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then
91b1417d
AC
4885 return False;
4886
c7c7dd3a
EB
4887 -- If we know that we have a small (at most the maximum integer size)
4888 -- record or bit-packed array, then everything is fine, since the back
4889 -- end can handle these cases correctly.
91b1417d 4890
c7c7dd3a 4891 elsif Esize (Comp) <= System_Max_Integer_Size
0e564ab4 4892 and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
91b1417d
AC
4893 then
4894 return False;
4895
dc7c0c4d
AC
4896 -- Otherwise if the component is not byte aligned, we know we have the
4897 -- nasty unaligned case.
91b1417d
AC
4898
4899 elsif Normalized_First_Bit (Comp) /= Uint_0
4900 or else Esize (Comp) mod System_Storage_Unit /= Uint_0
4901 then
4902 return True;
4903
4904 -- If we are large and byte aligned, then OK at this level
4905
4906 else
4907 return False;
4908 end if;
4909 end Component_May_Be_Bit_Aligned;
4910
1e3ed0fc
RD
4911 -------------------------------
4912 -- Convert_To_Actual_Subtype --
4913 -------------------------------
4914
4915 procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is
4916 Act_ST : Entity_Id;
4917
4918 begin
4919 Act_ST := Get_Actual_Subtype (Exp);
4920
4921 if Act_ST = Etype (Exp) then
4922 return;
4923 else
4924 Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp)));
4925 Analyze_And_Resolve (Exp, Act_ST);
4926 end if;
4927 end Convert_To_Actual_Subtype;
4928
1923d2d6
JM
4929 -----------------------------------
4930 -- Corresponding_Runtime_Package --
4931 -----------------------------------
4932
4933 function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is
ac8380d5
AC
4934 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean;
4935 -- Return True if protected type T has one entry and the maximum queue
4936 -- length is one.
4937
4938 --------------------------------
4939 -- Has_One_Entry_And_No_Queue --
4940 --------------------------------
4941
4942 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean is
6413509b 4943 Item : Entity_Id;
ac8380d5 4944 Is_First : Boolean := True;
6413509b 4945
ac8380d5 4946 begin
6413509b
AC
4947 Item := First_Entity (T);
4948 while Present (Item) loop
4949 if Is_Entry (Item) then
ac8380d5 4950
6413509b
AC
4951 -- The protected type has more than one entry
4952
4953 if not Is_First then
ac8380d5
AC
4954 return False;
4955 end if;
4956
6413509b
AC
4957 -- The queue length is not one
4958
ac8380d5 4959 if not Restriction_Active (No_Entry_Queue)
6413509b 4960 and then Get_Max_Queue_Length (Item) /= Uint_1
ac8380d5 4961 then
ac8380d5
AC
4962 return False;
4963 end if;
4964
4965 Is_First := False;
4966 end if;
4967
6413509b 4968 Next_Entity (Item);
ac8380d5
AC
4969 end loop;
4970
4971 return True;
4972 end Has_One_Entry_And_No_Queue;
4973
6413509b
AC
4974 -- Local variables
4975
1923d2d6
JM
4976 Pkg_Id : RTU_Id := RTU_Null;
4977
6413509b
AC
4978 -- Start of processing for Corresponding_Runtime_Package
4979
1923d2d6
JM
4980 begin
4981 pragma Assert (Is_Concurrent_Type (Typ));
4982
5188952e 4983 if Is_Protected_Type (Typ) then
1923d2d6 4984 if Has_Entries (Typ)
65df5b71
HK
4985
4986 -- A protected type without entries that covers an interface and
4987 -- overrides the abstract routines with protected procedures is
4988 -- considered equivalent to a protected type with entries in the
f3d0f304 4989 -- context of dispatching select statements. It is sufficient to
65df5b71
HK
4990 -- check for the presence of an interface list in the declaration
4991 -- node to recognize this case.
4992
4993 or else Present (Interface_List (Parent (Typ)))
27a8f150
AC
4994
4995 -- Protected types with interrupt handlers (when not using a
4996 -- restricted profile) are also considered equivalent to
4997 -- protected types with entries. The types which are used
4998 -- (Static_Interrupt_Protection and Dynamic_Interrupt_Protection)
4999 -- are derived from Protection_Entries.
5000
5001 or else (Has_Attach_Handler (Typ) and then not Restricted_Profile)
5002 or else Has_Interrupt_Handler (Typ)
1923d2d6
JM
5003 then
5004 if Abort_Allowed
a54ffd6c 5005 or else Restriction_Active (No_Select_Statements) = False
ac8380d5 5006 or else not Has_One_Entry_And_No_Queue (Typ)
1923d2d6 5007 or else (Has_Attach_Handler (Typ)
dc36a7e3 5008 and then not Restricted_Profile)
1923d2d6
JM
5009 then
5010 Pkg_Id := System_Tasking_Protected_Objects_Entries;
5011 else
5012 Pkg_Id := System_Tasking_Protected_Objects_Single_Entry;
5013 end if;
5014
5015 else
5016 Pkg_Id := System_Tasking_Protected_Objects;
5017 end if;
5018 end if;
5019
5020 return Pkg_Id;
5021 end Corresponding_Runtime_Package;
5022
70482933
RK
5023 -----------------------------------
5024 -- Current_Sem_Unit_Declarations --
5025 -----------------------------------
5026
5027 function Current_Sem_Unit_Declarations return List_Id is
5028 U : Node_Id := Unit (Cunit (Current_Sem_Unit));
5029 Decls : List_Id;
5030
5031 begin
5032 -- If the current unit is a package body, locate the visible
5033 -- declarations of the package spec.
5034
5035 if Nkind (U) = N_Package_Body then
5036 U := Unit (Library_Unit (Cunit (Current_Sem_Unit)));
5037 end if;
5038
5039 if Nkind (U) = N_Package_Declaration then
5040 U := Specification (U);
5041 Decls := Visible_Declarations (U);
5042
5043 if No (Decls) then
5044 Decls := New_List;
5045 Set_Visible_Declarations (U, Decls);
5046 end if;
5047
5048 else
5049 Decls := Declarations (U);
5050
5051 if No (Decls) then
5052 Decls := New_List;
5053 Set_Declarations (U, Decls);
5054 end if;
5055 end if;
5056
5057 return Decls;
5058 end Current_Sem_Unit_Declarations;
5059
5060 -----------------------
5061 -- Duplicate_Subexpr --
5062 -----------------------
5063
5064 function Duplicate_Subexpr
a43f6434
AC
5065 (Exp : Node_Id;
5066 Name_Req : Boolean := False;
5067 Renaming_Req : Boolean := False) return Node_Id
70482933
RK
5068 is
5069 begin
a43f6434 5070 Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
70482933
RK
5071 return New_Copy_Tree (Exp);
5072 end Duplicate_Subexpr;
5073
8cbb664e
MG
5074 ---------------------------------
5075 -- Duplicate_Subexpr_No_Checks --
5076 ---------------------------------
5077
5078 function Duplicate_Subexpr_No_Checks
2934b84a
AC
5079 (Exp : Node_Id;
5080 Name_Req : Boolean := False;
5081 Renaming_Req : Boolean := False;
5082 Related_Id : Entity_Id := Empty;
5083 Is_Low_Bound : Boolean := False;
5084 Is_High_Bound : Boolean := False) return Node_Id
8cbb664e
MG
5085 is
5086 New_Exp : Node_Id;
a43f6434 5087
8cbb664e 5088 begin
2934b84a
AC
5089 Remove_Side_Effects
5090 (Exp => Exp,
5091 Name_Req => Name_Req,
5092 Renaming_Req => Renaming_Req,
5093 Related_Id => Related_Id,
5094 Is_Low_Bound => Is_Low_Bound,
5095 Is_High_Bound => Is_High_Bound);
5096
8cbb664e
MG
5097 New_Exp := New_Copy_Tree (Exp);
5098 Remove_Checks (New_Exp);
5099 return New_Exp;
5100 end Duplicate_Subexpr_No_Checks;
5101
5102 -----------------------------------
5103 -- Duplicate_Subexpr_Move_Checks --
5104 -----------------------------------
5105
5106 function Duplicate_Subexpr_Move_Checks
a43f6434
AC
5107 (Exp : Node_Id;
5108 Name_Req : Boolean := False;
5109 Renaming_Req : Boolean := False) return Node_Id
8cbb664e
MG
5110 is
5111 New_Exp : Node_Id;
a43f6434 5112
8cbb664e 5113 begin
a43f6434 5114 Remove_Side_Effects (Exp, Name_Req, Renaming_Req);
8cbb664e
MG
5115 New_Exp := New_Copy_Tree (Exp);
5116 Remove_Checks (Exp);
5117 return New_Exp;
5118 end Duplicate_Subexpr_Move_Checks;
5119
341e0bb6
JS
5120 -------------------------
5121 -- Enclosing_Init_Proc --
5122 -------------------------
5123
5124 function Enclosing_Init_Proc return Entity_Id is
5125 S : Entity_Id;
5126
5127 begin
5128 S := Current_Scope;
5129 while Present (S) and then S /= Standard_Standard loop
5130 if Is_Init_Proc (S) then
5131 return S;
5132 else
5133 S := Scope (S);
5134 end if;
5135 end loop;
5136
5137 return Empty;
5138 end Enclosing_Init_Proc;
5139
70482933
RK
5140 --------------------
5141 -- Ensure_Defined --
5142 --------------------
5143
5144 procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is
5145 IR : Node_Id;
70482933
RK
5146
5147 begin
aa9a7dd7
AC
5148 -- An itype reference must only be created if this is a local itype, so
5149 -- that gigi can elaborate it on the proper objstack.
86cde7b1 5150
0e564ab4 5151 if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then
70482933
RK
5152 IR := Make_Itype_Reference (Sloc (N));
5153 Set_Itype (IR, Typ);
86cde7b1 5154 Insert_Action (N, IR);
70482933
RK
5155 end if;
5156 end Ensure_Defined;
5157
c42e6724
HK
5158 --------------------
5159 -- Entry_Names_OK --
5160 --------------------
5161
5162 function Entry_Names_OK return Boolean is
5163 begin
5164 return
5165 not Restricted_Profile
5166 and then not Global_Discard_Names
5167 and then not Restriction_Active (No_Implicit_Heap_Allocations)
5168 and then not Restriction_Active (No_Local_Allocators);
5169 end Entry_Names_OK;
5170
cc570be6
AC
5171 -------------------
5172 -- Evaluate_Name --
5173 -------------------
5174
5175 procedure Evaluate_Name (Nam : Node_Id) is
cc570be6 5176 begin
cd5acda5 5177 case Nkind (Nam) is
1a3680ff
PT
5178 -- For an aggregate, force its evaluation
5179
5180 when N_Aggregate =>
5181 Force_Evaluation (Nam);
5182
5183 -- For an attribute reference or an indexed component, evaluate the
5184 -- prefix, which is itself a name, recursively, and then force the
5185 -- evaluation of all the subscripts (or attribute expressions).
5186
cd5acda5
YM
5187 when N_Attribute_Reference
5188 | N_Indexed_Component
5189 =>
5190 Evaluate_Name (Prefix (Nam));
cc570be6 5191
cd5acda5
YM
5192 declare
5193 E : Node_Id;
cc570be6 5194
cd5acda5
YM
5195 begin
5196 E := First (Expressions (Nam));
5197 while Present (E) loop
5198 Force_Evaluation (E);
cc570be6 5199
dc67cfea 5200 if Is_Rewrite_Substitution (E) then
62c7d441
AC
5201 Set_Do_Range_Check
5202 (E, Do_Range_Check (Original_Node (E)));
cd5acda5 5203 end if;
cc570be6 5204
cd5acda5
YM
5205 Next (E);
5206 end loop;
5207 end;
cc570be6 5208
cd5acda5
YM
5209 -- For an explicit dereference, we simply force the evaluation of
5210 -- the name expression. The dereference provides a value that is the
5211 -- address for the renamed object, and it is precisely this value
5212 -- that we want to preserve.
cc570be6 5213
cd5acda5
YM
5214 when N_Explicit_Dereference =>
5215 Force_Evaluation (Prefix (Nam));
cc570be6 5216
df7507a6 5217 -- For a function call, we evaluate the call; same for an operator
cc570be6 5218
df7507a6
PT
5219 when N_Function_Call
5220 | N_Op
5221 =>
cd5acda5 5222 Force_Evaluation (Nam);
cc570be6 5223
1a3680ff 5224 -- For a qualified expression, we evaluate the expression
cc570be6 5225
cd5acda5 5226 when N_Qualified_Expression =>
1a3680ff 5227 Evaluate_Name (Expression (Nam));
cc570be6 5228
cd5acda5 5229 -- For a selected component, we simply evaluate the prefix
cc570be6 5230
cd5acda5
YM
5231 when N_Selected_Component =>
5232 Evaluate_Name (Prefix (Nam));
cc570be6 5233
cd5acda5
YM
5234 -- For a slice, we evaluate the prefix, as for the indexed component
5235 -- case and then, if there is a range present, either directly or as
5236 -- the constraint of a discrete subtype indication, we evaluate the
5237 -- two bounds of this range.
cc570be6 5238
cd5acda5
YM
5239 when N_Slice =>
5240 Evaluate_Name (Prefix (Nam));
5241 Evaluate_Slice_Bounds (Nam);
cc570be6 5242
cd5acda5
YM
5243 -- For a type conversion, the expression of the conversion must be
5244 -- the name of an object, and we simply need to evaluate this name.
cc570be6 5245
cd5acda5
YM
5246 when N_Type_Conversion =>
5247 Evaluate_Name (Expression (Nam));
5248
df7507a6
PT
5249 -- The remaining cases are direct name and character literal. In all
5250 -- these cases, we do nothing, since we want to reevaluate each time
5251 -- the renamed object is used. ??? There are more remaining cases, at
5252 -- least in the GNATprove_Mode, where this routine is called in more
5253 -- contexts than in GNAT.
cd5acda5
YM
5254
5255 when others =>
5256 null;
5257 end case;
cc570be6
AC
5258 end Evaluate_Name;
5259
08cd7c2f
AC
5260 ---------------------------
5261 -- Evaluate_Slice_Bounds --
5262 ---------------------------
5263
5264 procedure Evaluate_Slice_Bounds (Slice : Node_Id) is
5265 DR : constant Node_Id := Discrete_Range (Slice);
5266 Constr : Node_Id;
5267 Rexpr : Node_Id;
5268
5269 begin
5270 if Nkind (DR) = N_Range then
5271 Force_Evaluation (Low_Bound (DR));
5272 Force_Evaluation (High_Bound (DR));
5273
5274 elsif Nkind (DR) = N_Subtype_Indication then
5275 Constr := Constraint (DR);
5276
5277 if Nkind (Constr) = N_Range_Constraint then
5278 Rexpr := Range_Expression (Constr);
5279
5280 Force_Evaluation (Low_Bound (Rexpr));
5281 Force_Evaluation (High_Bound (Rexpr));
5282 end if;
5283 end if;
5284 end Evaluate_Slice_Bounds;
5285
70482933
RK
5286 ---------------------
5287 -- Evolve_And_Then --
5288 ---------------------
5289
5290 procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is
5291 begin
5292 if No (Cond) then
5293 Cond := Cond1;
5294 else
5295 Cond :=
5296 Make_And_Then (Sloc (Cond1),
5297 Left_Opnd => Cond,
5298 Right_Opnd => Cond1);
5299 end if;
5300 end Evolve_And_Then;
5301
5302 --------------------
5303 -- Evolve_Or_Else --
5304 --------------------
5305
5306 procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is
5307 begin
5308 if No (Cond) then
5309 Cond := Cond1;
5310 else
5311 Cond :=
5312 Make_Or_Else (Sloc (Cond1),
5313 Left_Opnd => Cond,
5314 Right_Opnd => Cond1);
5315 end if;
5316 end Evolve_Or_Else;
5317
9e92ad49
AC
5318 -----------------------------------------
5319 -- Expand_Static_Predicates_In_Choices --
5320 -----------------------------------------
5321
5322 procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is
4a08c95c 5323 pragma Assert (Nkind (N) in N_Case_Statement_Alternative | N_Variant);
9e92ad49
AC
5324
5325 Choices : constant List_Id := Discrete_Choices (N);
5326
5327 Choice : Node_Id;
5328 Next_C : Node_Id;
5329 P : Node_Id;
5330 C : Node_Id;
5331
5332 begin
5333 Choice := First (Choices);
5334 while Present (Choice) loop
5335 Next_C := Next (Choice);
5336
5337 -- Check for name of subtype with static predicate
5338
5339 if Is_Entity_Name (Choice)
5340 and then Is_Type (Entity (Choice))
5341 and then Has_Predicates (Entity (Choice))
5342 then
5343 -- Loop through entries in predicate list, converting to choices
5344 -- and inserting in the list before the current choice. Note that
5345 -- if the list is empty, corresponding to a False predicate, then
5346 -- no choices are inserted.
5347
60f908dd 5348 P := First (Static_Discrete_Predicate (Entity (Choice)));
9e92ad49
AC
5349 while Present (P) loop
5350
5351 -- If low bound and high bounds are equal, copy simple choice
5352
5353 if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then
5354 C := New_Copy (Low_Bound (P));
5355
5356 -- Otherwise copy a range
5357
5358 else
5359 C := New_Copy (P);
5360 end if;
5361
5362 -- Change Sloc to referencing choice (rather than the Sloc of
15918371 5363 -- the predicate declaration element itself).
9e92ad49
AC
5364
5365 Set_Sloc (C, Sloc (Choice));
5366 Insert_Before (Choice, C);
5367 Next (P);
5368 end loop;
5369
5370 -- Delete the predicated entry
5371
5372 Remove (Choice);
5373 end if;
5374
5375 -- Move to next choice to check
5376
5377 Choice := Next_C;
5378 end loop;
ebea257e
HK
5379
5380 Set_Has_SP_Choice (N, False);
9e92ad49
AC
5381 end Expand_Static_Predicates_In_Choices;
5382
70482933
RK
5383 ------------------------------
5384 -- Expand_Subtype_From_Expr --
5385 ------------------------------
5386
5387 -- This function is applicable for both static and dynamic allocation of
5388 -- objects which are constrained by an initial expression. Basically it
5389 -- transforms an unconstrained subtype indication into a constrained one.
273adcdf 5390
70482933 5391 -- The expression may also be transformed in certain cases in order to
05350ac6
BD
5392 -- avoid multiple evaluation. In the static allocation case, the general
5393 -- scheme is:
70482933
RK
5394
5395 -- Val : T := Expr;
5396
5397 -- is transformed into
5398
65e5747e 5399 -- Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr;
70482933
RK
5400 --
5401 -- Here are the main cases :
5402 --
5403 -- <if Expr is a Slice>
5404 -- Val : T ([Index_Subtype (Expr)]) := Expr;
5405 --
5406 -- <elsif Expr is a String Literal>
5407 -- Val : T (T'First .. T'First + Length (string literal) - 1) := Expr;
5408 --
5409 -- <elsif Expr is Constrained>
5410 -- subtype T is Type_Of_Expr
5411 -- Val : T := Expr;
5412 --
5413 -- <elsif Expr is an entity_name>
638e383e 5414 -- Val : T (constraints taken from Expr) := Expr;
70482933
RK
5415 --
5416 -- <else>
5417 -- type Axxx is access all T;
5418 -- Rval : Axxx := Expr'ref;
638e383e 5419 -- Val : T (constraints taken from Rval) := Rval.all;
70482933
RK
5420
5421 -- ??? note: when the Expression is allocated in the secondary stack
5422 -- we could use it directly instead of copying it by declaring
5423 -- Val : T (...) renames Rval.all
5424
5425 procedure Expand_Subtype_From_Expr
5426 (N : Node_Id;
5427 Unc_Type : Entity_Id;
5428 Subtype_Indic : Node_Id;
d9307840
HK
5429 Exp : Node_Id;
5430 Related_Id : Entity_Id := Empty)
70482933
RK
5431 is
5432 Loc : constant Source_Ptr := Sloc (N);
5433 Exp_Typ : constant Entity_Id := Etype (Exp);
5434 T : Entity_Id;
5435
5436 begin
5437 -- In general we cannot build the subtype if expansion is disabled,
5438 -- because internal entities may not have been defined. However, to
f2e7ec10
AC
5439 -- avoid some cascaded errors, we try to continue when the expression is
5440 -- an array (or string), because it is safe to compute the bounds. It is
5441 -- in fact required to do so even in a generic context, because there
5442 -- may be constants that depend on the bounds of a string literal, both
5443 -- standard string types and more generally arrays of characters.
70482933 5444
5dd63272
YM
5445 -- In GNATprove mode, these extra subtypes are not needed, unless Exp is
5446 -- a static expression. In that case, the subtype will be constrained
5447 -- while the original type might be unconstrained, so expanding the type
5448 -- is necessary both for passing legality checks in GNAT and for precise
5449 -- analysis in GNATprove.
5450
134f52b9 5451 if GNATprove_Mode and then not Is_Static_Expression (Exp) then
70482933
RK
5452 return;
5453 end if;
5454
ebb6b0bd
AC
5455 if not Expander_Active
5456 and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp)))
5457 then
f5da7a97
YM
5458 return;
5459 end if;
5460
70482933
RK
5461 if Nkind (Exp) = N_Slice then
5462 declare
5463 Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ));
5464
5465 begin
5466 Rewrite (Subtype_Indic,
5467 Make_Subtype_Indication (Loc,
e4494292 5468 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
70482933
RK
5469 Constraint =>
5470 Make_Index_Or_Discriminant_Constraint (Loc,
5471 Constraints => New_List
e4494292 5472 (New_Occurrence_Of (Slice_Type, Loc)))));
70482933 5473
e14c931f 5474 -- This subtype indication may be used later for constraint checks
70482933 5475 -- we better make sure that if a variable was used as a bound of
134f52b9 5476 -- the original slice, its value is frozen.
70482933 5477
08cd7c2f 5478 Evaluate_Slice_Bounds (Exp);
70482933
RK
5479 end;
5480
5481 elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then
5482 Rewrite (Subtype_Indic,
5483 Make_Subtype_Indication (Loc,
e4494292 5484 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc),
70482933
RK
5485 Constraint =>
5486 Make_Index_Or_Discriminant_Constraint (Loc,
5487 Constraints => New_List (
5488 Make_Literal_Range (Loc,
f91b40db 5489 Literal_Typ => Exp_Typ)))));
70482933 5490
9a7049fd 5491 -- If the type of the expression is an internally generated type it
872c2f37
RD
5492 -- may not be necessary to create a new subtype. However there are two
5493 -- exceptions: references to the current instances, and aliased array
bb072d1c 5494 -- object declarations for which the back end has to create a template.
9a7049fd 5495
70482933
RK
5496 elsif Is_Constrained (Exp_Typ)
5497 and then not Is_Class_Wide_Type (Unc_Type)
9a7049fd
AC
5498 and then
5499 (Nkind (N) /= N_Object_Declaration
872c2f37
RD
5500 or else not Is_Entity_Name (Expression (N))
5501 or else not Comes_From_Source (Entity (Expression (N)))
5502 or else not Is_Array_Type (Exp_Typ)
5503 or else not Aliased_Present (N))
70482933
RK
5504 then
5505 if Is_Itype (Exp_Typ) then
5506
758c442c 5507 -- Within an initialization procedure, a selected component
273adcdf
AC
5508 -- denotes a component of the enclosing record, and it appears as
5509 -- an actual in a call to its own initialization procedure. If
5510 -- this component depends on the outer discriminant, we must
758c442c 5511 -- generate the proper actual subtype for it.
70482933 5512
758c442c
GD
5513 if Nkind (Exp) = N_Selected_Component
5514 and then Within_Init_Proc
5515 then
5516 declare
5517 Decl : constant Node_Id :=
5518 Build_Actual_Subtype_Of_Component (Exp_Typ, Exp);
5519 begin
5520 if Present (Decl) then
5521 Insert_Action (N, Decl);
5522 T := Defining_Identifier (Decl);
5523 else
5524 T := Exp_Typ;
5525 end if;
5526 end;
5527
9a7049fd 5528 -- No need to generate a new subtype
758c442c
GD
5529
5530 else
5531 T := Exp_Typ;
5532 end if;
70482933
RK
5533
5534 else
092ef350 5535 T := Make_Temporary (Loc, 'T');
70482933
RK
5536
5537 Insert_Action (N,
5538 Make_Subtype_Declaration (Loc,
5539 Defining_Identifier => T,
e4494292 5540 Subtype_Indication => New_Occurrence_Of (Exp_Typ, Loc)));
70482933 5541
273adcdf
AC
5542 -- This type is marked as an itype even though it has an explicit
5543 -- declaration since otherwise Is_Generic_Actual_Type can get
5544 -- set, resulting in the generation of spurious errors. (See
5545 -- sem_ch8.Analyze_Package_Renaming and sem_type.covers)
70482933
RK
5546
5547 Set_Is_Itype (T);
5548 Set_Associated_Node_For_Itype (T, Exp);
5549 end if;
5550
e4494292 5551 Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc));
70482933 5552
0a69df7c 5553 -- Nothing needs to be done for private types with unknown discriminants
3f5bb1b8
AC
5554 -- if the underlying type is not an unconstrained composite type or it
5555 -- is an unchecked union.
70482933
RK
5556
5557 elsif Is_Private_Type (Unc_Type)
5558 and then Has_Unknown_Discriminants (Unc_Type)
5559 and then (not Is_Composite_Type (Underlying_Type (Unc_Type))
0a69df7c
AC
5560 or else Is_Constrained (Underlying_Type (Unc_Type))
5561 or else Is_Unchecked_Union (Underlying_Type (Unc_Type)))
70482933
RK
5562 then
5563 null;
5564
58a9d876
AC
5565 -- Case of derived type with unknown discriminants where the parent type
5566 -- also has unknown discriminants.
f4d379b8
HK
5567
5568 elsif Is_Record_Type (Unc_Type)
5569 and then not Is_Class_Wide_Type (Unc_Type)
5570 and then Has_Unknown_Discriminants (Unc_Type)
5571 and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type))
5572 then
58a9d876
AC
5573 -- Nothing to be done if no underlying record view available
5574
913e4b36 5575 -- If this is a limited type derived from a type with unknown
9313a26a
AC
5576 -- discriminants, do not expand either, so that subsequent expansion
5577 -- of the call can add build-in-place parameters to call.
913e4b36
ES
5578
5579 if No (Underlying_Record_View (Unc_Type))
5580 or else Is_Limited_Type (Unc_Type)
5581 then
58a9d876
AC
5582 null;
5583
5584 -- Otherwise use the Underlying_Record_View to create the proper
5585 -- constrained subtype for an object of a derived type with unknown
5586 -- discriminants.
5587
5588 else
5589 Remove_Side_Effects (Exp);
5590 Rewrite (Subtype_Indic,
5591 Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type)));
5592 end if;
f4d379b8 5593
0e41a941
AC
5594 -- Renamings of class-wide interface types require no equivalent
5595 -- constrained type declarations because we only need to reference
df3e68b1
HK
5596 -- the tag component associated with the interface. The same is
5597 -- presumably true for class-wide types in general, so this test
5598 -- is broadened to include all class-wide renamings, which also
5599 -- avoids cases of unbounded recursion in Remove_Side_Effects.
5600 -- (Is this really correct, or are there some cases of class-wide
5601 -- renamings that require action in this procedure???)
0e41a941
AC
5602
5603 elsif Present (N)
5604 and then Nkind (N) = N_Object_Renaming_Declaration
df3e68b1 5605 and then Is_Class_Wide_Type (Unc_Type)
0e41a941 5606 then
0e41a941
AC
5607 null;
5608
885c4871 5609 -- In Ada 95 nothing to be done if the type of the expression is limited
aa9a7dd7
AC
5610 -- because in this case the expression cannot be copied, and its use can
5611 -- only be by reference.
10b93b2e 5612
885c4871 5613 -- In Ada 2005 the context can be an object declaration whose expression
0712790c
ES
5614 -- is a function that returns in place. If the nominal subtype has
5615 -- unknown discriminants, the call still provides constraints on the
5616 -- object, and we have to create an actual subtype from it.
5617
5618 -- If the type is class-wide, the expression is dynamically tagged and
5619 -- we do not create an actual subtype either. Ditto for an interface.
0187b60e
AC
5620 -- For now this applies only if the type is immutably limited, and the
5621 -- function being called is build-in-place. This will have to be revised
5622 -- when build-in-place functions are generalized to other types.
0712790c 5623
51245e2d 5624 elsif Is_Limited_View (Exp_Typ)
0712790c
ES
5625 and then
5626 (Is_Class_Wide_Type (Exp_Typ)
5627 or else Is_Interface (Exp_Typ)
5628 or else not Has_Unknown_Discriminants (Exp_Typ)
5629 or else not Is_Composite_Type (Unc_Type))
5630 then
5631 null;
5632
e3946607 5633 -- For limited objects initialized with build-in-place function calls,
86cde7b1
RD
5634 -- nothing to be done; otherwise we prematurely introduce an N_Reference
5635 -- node in the expression initializing the object, which breaks the
5636 -- circuitry that detects and adds the additional arguments to the
5637 -- called function.
5638
5639 elsif Is_Build_In_Place_Function_Call (Exp) then
5640 null;
5641
e3946607
GD
5642 -- If the expression is an uninitialized aggregate, no need to build
5643 -- a subtype from the expression, because this may require the use of
5644 -- dynamic memory to create the object.
a46fa651
ES
5645
5646 elsif Is_Uninitialized_Aggregate (Exp, Exp_Typ) then
5647 Rewrite (Subtype_Indic, New_Occurrence_Of (Etype (Exp), Sloc (N)));
5648 if Nkind (N) = N_Object_Declaration then
5649 Set_Expression (N, Empty);
5650 Set_No_Initialization (N);
5651 end if;
5652
70482933
RK
5653 else
5654 Remove_Side_Effects (Exp);
5655 Rewrite (Subtype_Indic,
d9307840 5656 Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id));
70482933
RK
5657 end if;
5658 end Expand_Subtype_From_Expr;
5659
28ccbd3f
AC
5660 ---------------------------------------------
5661 -- Expression_Contains_Primitives_Calls_Of --
5662 ---------------------------------------------
5663
5664 function Expression_Contains_Primitives_Calls_Of
5665 (Expr : Node_Id;
5666 Typ : Entity_Id) return Boolean
5667 is
5668 U_Typ : constant Entity_Id := Unique_Entity (Typ);
5669
bf604a5e 5670 Calls_OK : Boolean := False;
eb2d5ccc 5671 -- This flag is set to True when expression Expr contains at least one
e0666fc6 5672 -- call to a nondispatching primitive function of Typ.
bf604a5e 5673
28ccbd3f 5674 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result;
178c3cba 5675 -- Search for nondispatching calls to primitive functions of type Typ
28ccbd3f
AC
5676
5677 ----------------------------
5678 -- Search_Primitive_Calls --
5679 ----------------------------
5680
eb2d5ccc 5681 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result is
bf604a5e
AC
5682 Disp_Typ : Entity_Id;
5683 Subp : Entity_Id;
5684
28ccbd3f 5685 begin
e0666fc6 5686 -- Detect a function call that could denote a nondispatching
bf604a5e
AC
5687 -- primitive of the input type.
5688
5689 if Nkind (N) = N_Function_Call
5690 and then Is_Entity_Name (Name (N))
28ccbd3f 5691 then
bf604a5e 5692 Subp := Entity (Name (N));
28ccbd3f 5693
e0666fc6 5694 -- Do not consider function calls with a controlling argument, as
eb2d5ccc 5695 -- those are always dispatching calls.
bf604a5e
AC
5696
5697 if Is_Dispatching_Operation (Subp)
5698 and then No (Controlling_Argument (N))
28ccbd3f 5699 then
bf604a5e 5700 Disp_Typ := Find_Dispatching_Type (Subp);
28ccbd3f 5701
eb2d5ccc
AC
5702 -- To qualify as a suitable primitive, the dispatching type of
5703 -- the function must be the input type.
28ccbd3f 5704
bf604a5e
AC
5705 if Present (Disp_Typ)
5706 and then Unique_Entity (Disp_Typ) = U_Typ
5707 then
5708 Calls_OK := True;
5709
e0666fc6 5710 -- There is no need to continue the traversal, as one such
eb2d5ccc 5711 -- call suffices.
bf604a5e
AC
5712
5713 return Abandon;
5714 end if;
28ccbd3f
AC
5715 end if;
5716 end if;
5717
5718 return OK;
5719 end Search_Primitive_Calls;
5720
eb2d5ccc 5721 procedure Search_Calls is new Traverse_Proc (Search_Primitive_Calls);
28ccbd3f
AC
5722
5723 -- Start of processing for Expression_Contains_Primitives_Calls_Of_Type
5724
5725 begin
bf604a5e
AC
5726 Search_Calls (Expr);
5727 return Calls_OK;
28ccbd3f
AC
5728 end Expression_Contains_Primitives_Calls_Of;
5729
760804f3
AC
5730 ----------------------
5731 -- Finalize_Address --
5732 ----------------------
5733
5734 function Finalize_Address (Typ : Entity_Id) return Entity_Id is
78170c8e 5735 Btyp : constant Entity_Id := Base_Type (Typ);
760804f3
AC
5736 Utyp : Entity_Id := Typ;
5737
5738 begin
5739 -- Handle protected class-wide or task class-wide types
5740
5741 if Is_Class_Wide_Type (Utyp) then
5742 if Is_Concurrent_Type (Root_Type (Utyp)) then
5743 Utyp := Root_Type (Utyp);
5744
5745 elsif Is_Private_Type (Root_Type (Utyp))
5746 and then Present (Full_View (Root_Type (Utyp)))
5747 and then Is_Concurrent_Type (Full_View (Root_Type (Utyp)))
5748 then
5749 Utyp := Full_View (Root_Type (Utyp));
5750 end if;
5751 end if;
5752
5753 -- Handle private types
5754
5755 if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then
5756 Utyp := Full_View (Utyp);
5757 end if;
5758
5759 -- Handle protected and task types
5760
5761 if Is_Concurrent_Type (Utyp)
5762 and then Present (Corresponding_Record_Type (Utyp))
5763 then
5764 Utyp := Corresponding_Record_Type (Utyp);
5765 end if;
5766
5767 Utyp := Underlying_Type (Base_Type (Utyp));
5768
5769 -- Deal with untagged derivation of private views. If the parent is
5770 -- now known to be protected, the finalization routine is the one
5771 -- defined on the corresponding record of the ancestor (corresponding
5772 -- records do not automatically inherit operations, but maybe they
5773 -- should???)
5774
78170c8e
EB
5775 if Is_Untagged_Derivation (Btyp) then
5776 if Is_Protected_Type (Btyp) then
5777 Utyp := Corresponding_Record_Type (Root_Type (Btyp));
46413d9e 5778
760804f3 5779 else
78170c8e 5780 Utyp := Underlying_Type (Root_Type (Btyp));
760804f3
AC
5781
5782 if Is_Protected_Type (Utyp) then
5783 Utyp := Corresponding_Record_Type (Utyp);
5784 end if;
5785 end if;
5786 end if;
5787
5788 -- If the underlying_type is a subtype, we are dealing with the
5789 -- completion of a private type. We need to access the base type and
5790 -- generate a conversion to it.
5791
5792 if Utyp /= Base_Type (Utyp) then
5793 pragma Assert (Is_Private_Type (Typ));
5794
5795 Utyp := Base_Type (Utyp);
5796 end if;
5797
5798 -- When dealing with an internally built full view for a type with
5799 -- unknown discriminants, use the original record type.
5800
5801 if Is_Underlying_Record_View (Utyp) then
5802 Utyp := Etype (Utyp);
5803 end if;
5804
5805 return TSS (Utyp, TSS_Finalize_Address);
5806 end Finalize_Address;
5807
758c442c 5808 ------------------------
f4d379b8 5809 -- Find_Interface_ADT --
758c442c
GD
5810 ------------------------
5811
3ca505dc
JM
5812 function Find_Interface_ADT
5813 (T : Entity_Id;
ac4d6407 5814 Iface : Entity_Id) return Elmt_Id
3ca505dc 5815 is
ce2b6ba5
JM
5816 ADT : Elmt_Id;
5817 Typ : Entity_Id := T;
3ca505dc
JM
5818
5819 begin
dee4682a
JM
5820 pragma Assert (Is_Interface (Iface));
5821
3ca505dc
JM
5822 -- Handle private types
5823
0e564ab4 5824 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
3ca505dc
JM
5825 Typ := Full_View (Typ);
5826 end if;
5827
5828 -- Handle access types
5829
5830 if Is_Access_Type (Typ) then
841dd0f5 5831 Typ := Designated_Type (Typ);
3ca505dc
JM
5832 end if;
5833
5834 -- Handle task and protected types implementing interfaces
5835
dee4682a 5836 if Is_Concurrent_Type (Typ) then
3ca505dc
JM
5837 Typ := Corresponding_Record_Type (Typ);
5838 end if;
5839
dee4682a
JM
5840 pragma Assert
5841 (not Is_Class_Wide_Type (Typ)
5842 and then Ekind (Typ) /= E_Incomplete_Type);
5843
4ac2477e 5844 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
ce2b6ba5
JM
5845 return First_Elmt (Access_Disp_Table (Typ));
5846
5847 else
872c2f37 5848 ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ))));
ce2b6ba5
JM
5849 while Present (ADT)
5850 and then Present (Related_Type (Node (ADT)))
5851 and then Related_Type (Node (ADT)) /= Iface
4ac2477e
JM
5852 and then not Is_Ancestor (Iface, Related_Type (Node (ADT)),
5853 Use_Full_View => True)
ce2b6ba5
JM
5854 loop
5855 Next_Elmt (ADT);
5856 end loop;
5857
5858 pragma Assert (Present (Related_Type (Node (ADT))));
5859 return ADT;
5860 end if;
3ca505dc
JM
5861 end Find_Interface_ADT;
5862
5863 ------------------------
5864 -- Find_Interface_Tag --
5865 ------------------------
5866
5867 function Find_Interface_Tag
dee4682a
JM
5868 (T : Entity_Id;
5869 Iface : Entity_Id) return Entity_Id
758c442c 5870 is
dcd5fd67 5871 AI_Tag : Entity_Id := Empty;
dee4682a 5872 Found : Boolean := False;
3ca505dc 5873 Typ : Entity_Id := T;
758c442c 5874
59e54267 5875 procedure Find_Tag (Typ : Entity_Id);
3ca505dc 5876 -- Internal subprogram used to recursively climb to the ancestors
758c442c 5877
ea985d95
RD
5878 --------------
5879 -- Find_Tag --
5880 --------------
758c442c 5881
59e54267 5882 procedure Find_Tag (Typ : Entity_Id) is
758c442c
GD
5883 AI_Elmt : Elmt_Id;
5884 AI : Node_Id;
5885
5886 begin
0e41a941
AC
5887 -- This routine does not handle the case in which the interface is an
5888 -- ancestor of Typ. That case is handled by the enclosing subprogram.
758c442c 5889
0e41a941 5890 pragma Assert (Typ /= Iface);
758c442c 5891
f4d379b8
HK
5892 -- Climb to the root type handling private types
5893
ce2b6ba5 5894 if Present (Full_View (Etype (Typ))) then
f4d379b8
HK
5895 if Full_View (Etype (Typ)) /= Typ then
5896 Find_Tag (Full_View (Etype (Typ)));
5897 end if;
758c442c 5898
f4d379b8 5899 elsif Etype (Typ) /= Typ then
3ca505dc 5900 Find_Tag (Etype (Typ));
758c442c
GD
5901 end if;
5902
5903 -- Traverse the list of interfaces implemented by the type
5904
5905 if not Found
ce2b6ba5
JM
5906 and then Present (Interfaces (Typ))
5907 and then not (Is_Empty_Elmt_List (Interfaces (Typ)))
758c442c 5908 then
10b93b2e 5909 -- Skip the tag associated with the primary table
758c442c 5910
ce2b6ba5
JM
5911 AI_Tag := Next_Tag_Component (First_Tag_Component (Typ));
5912 pragma Assert (Present (AI_Tag));
758c442c 5913
ce2b6ba5 5914 AI_Elmt := First_Elmt (Interfaces (Typ));
758c442c
GD
5915 while Present (AI_Elmt) loop
5916 AI := Node (AI_Elmt);
5917
4ac2477e
JM
5918 if AI = Iface
5919 or else Is_Ancestor (Iface, AI, Use_Full_View => True)
5920 then
758c442c
GD
5921 Found := True;
5922 return;
5923 end if;
5924
5925 AI_Tag := Next_Tag_Component (AI_Tag);
5926 Next_Elmt (AI_Elmt);
758c442c
GD
5927 end loop;
5928 end if;
3ca505dc
JM
5929 end Find_Tag;
5930
5931 -- Start of processing for Find_Interface_Tag
758c442c
GD
5932
5933 begin
f4d379b8
HK
5934 pragma Assert (Is_Interface (Iface));
5935
3ca505dc 5936 -- Handle access types
758c442c 5937
3ca505dc 5938 if Is_Access_Type (Typ) then
841dd0f5 5939 Typ := Designated_Type (Typ);
3ca505dc 5940 end if;
758c442c 5941
c6ad817f 5942 -- Handle class-wide types
758c442c 5943
c6ad817f
JM
5944 if Is_Class_Wide_Type (Typ) then
5945 Typ := Root_Type (Typ);
3ca505dc
JM
5946 end if;
5947
c6ad817f
JM
5948 -- Handle private types
5949
0e564ab4 5950 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then
c6ad817f 5951 Typ := Full_View (Typ);
10b93b2e
HK
5952 end if;
5953
5954 -- Handle entities from the limited view
5955
5956 if Ekind (Typ) = E_Incomplete_Type then
5957 pragma Assert (Present (Non_Limited_View (Typ)));
5958 Typ := Non_Limited_View (Typ);
5959 end if;
5960
c6ad817f
JM
5961 -- Handle task and protected types implementing interfaces
5962
5963 if Is_Concurrent_Type (Typ) then
5964 Typ := Corresponding_Record_Type (Typ);
5965 end if;
5966
0e41a941
AC
5967 -- If the interface is an ancestor of the type, then it shared the
5968 -- primary dispatch table.
5969
4ac2477e 5970 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then
0e41a941
AC
5971 return First_Tag_Component (Typ);
5972
5973 -- Otherwise we need to search for its associated tag component
5974
5975 else
5976 Find_Tag (Typ);
0e41a941
AC
5977 return AI_Tag;
5978 end if;
ce2b6ba5 5979 end Find_Interface_Tag;
ea985d95 5980
ca811241
BD
5981 ---------------------------
5982 -- Find_Optional_Prim_Op --
5983 ---------------------------
70482933 5984
ca811241
BD
5985 function Find_Optional_Prim_Op
5986 (T : Entity_Id; Name : Name_Id) return Entity_Id
5987 is
70482933
RK
5988 Prim : Elmt_Id;
5989 Typ : Entity_Id := T;
59e54267 5990 Op : Entity_Id;
70482933
RK
5991
5992 begin
5993 if Is_Class_Wide_Type (Typ) then
5994 Typ := Root_Type (Typ);
5995 end if;
5996
5997 Typ := Underlying_Type (Typ);
5998
59e54267
ES
5999 -- Loop through primitive operations
6000
70482933 6001 Prim := First_Elmt (Primitive_Operations (Typ));
59e54267
ES
6002 while Present (Prim) loop
6003 Op := Node (Prim);
6004
6005 -- We can retrieve primitive operations by name if it is an internal
6006 -- name. For equality we must check that both of its operands have
6007 -- the same type, to avoid confusion with user-defined equalities
3f833dc2 6008 -- than may have a asymmetric signature.
59e54267
ES
6009
6010 exit when Chars (Op) = Name
6011 and then
6012 (Name /= Name_Op_Eq
0e564ab4 6013 or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op)));
59e54267 6014
70482933 6015 Next_Elmt (Prim);
70482933
RK
6016 end loop;
6017
ca811241
BD
6018 return Node (Prim); -- Empty if not found
6019 end Find_Optional_Prim_Op;
70482933 6020
ca811241
BD
6021 ---------------------------
6022 -- Find_Optional_Prim_Op --
6023 ---------------------------
dee4682a 6024
ca811241 6025 function Find_Optional_Prim_Op
fbf5a39b
AC
6026 (T : Entity_Id;
6027 Name : TSS_Name_Type) return Entity_Id
6028 is
df3e68b1
HK
6029 Inher_Op : Entity_Id := Empty;
6030 Own_Op : Entity_Id := Empty;
6031 Prim_Elmt : Elmt_Id;
6032 Prim_Id : Entity_Id;
6033 Typ : Entity_Id := T;
fbf5a39b
AC
6034
6035 begin
6036 if Is_Class_Wide_Type (Typ) then
6037 Typ := Root_Type (Typ);
6038 end if;
6039
6040 Typ := Underlying_Type (Typ);
6041
df3e68b1
HK
6042 -- This search is based on the assertion that the dispatching version
6043 -- of the TSS routine always precedes the real primitive.
6a4d72a6 6044
df3e68b1
HK
6045 Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
6046 while Present (Prim_Elmt) loop
6047 Prim_Id := Node (Prim_Elmt);
7813a510 6048
df3e68b1
HK
6049 if Is_TSS (Prim_Id, Name) then
6050 if Present (Alias (Prim_Id)) then
6051 Inher_Op := Prim_Id;
6052 else
6053 Own_Op := Prim_Id;
6054 end if;
6a4d72a6 6055 end if;
df3e68b1
HK
6056
6057 Next_Elmt (Prim_Elmt);
fbf5a39b
AC
6058 end loop;
6059
df3e68b1
HK
6060 if Present (Own_Op) then
6061 return Own_Op;
6062 elsif Present (Inher_Op) then
6063 return Inher_Op;
6064 else
ca811241
BD
6065 return Empty;
6066 end if;
6067 end Find_Optional_Prim_Op;
6068
6069 ------------------
6070 -- Find_Prim_Op --
6071 ------------------
6072
6073 function Find_Prim_Op
6074 (T : Entity_Id; Name : Name_Id) return Entity_Id
6075 is
6076 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
6077 begin
6078 if No (Result) then
6079 raise Program_Error;
6080 end if;
6081
6082 return Result;
6083 end Find_Prim_Op;
6084
6085 ------------------
6086 -- Find_Prim_Op --
6087 ------------------
6088
6089 function Find_Prim_Op
6090 (T : Entity_Id;
6091 Name : TSS_Name_Type) return Entity_Id
6092 is
6093 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name);
6094 begin
6095 if No (Result) then
df3e68b1
HK
6096 raise Program_Error;
6097 end if;
ca811241
BD
6098
6099 return Result;
fbf5a39b
AC
6100 end Find_Prim_Op;
6101
65df5b71
HK
6102 ----------------------------
6103 -- Find_Protection_Object --
6104 ----------------------------
6105
6106 function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is
6107 S : Entity_Id;
6108
6109 begin
6110 S := Scop;
6111 while Present (S) loop
4a08c95c 6112 if Ekind (S) in E_Entry | E_Entry_Family | E_Function | E_Procedure
65df5b71
HK
6113 and then Present (Protection_Object (S))
6114 then
6115 return Protection_Object (S);
6116 end if;
6117
6118 S := Scope (S);
6119 end loop;
6120
6121 -- If we do not find a Protection object in the scope chain, then
6122 -- something has gone wrong, most likely the object was never created.
6123
6124 raise Program_Error;
6125 end Find_Protection_Object;
6126
df3e68b1
HK
6127 --------------------------
6128 -- Find_Protection_Type --
6129 --------------------------
6130
6131 function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is
6132 Comp : Entity_Id;
6133 Typ : Entity_Id := Conc_Typ;
6134
6135 begin
6136 if Is_Concurrent_Type (Typ) then
6137 Typ := Corresponding_Record_Type (Typ);
6138 end if;
6139
e0c32166
AC
6140 -- Since restriction violations are not considered serious errors, the
6141 -- expander remains active, but may leave the corresponding record type
6142 -- malformed. In such cases, component _object is not available so do
6143 -- not look for it.
6144
6145 if not Analyzed (Typ) then
6146 return Empty;
6147 end if;
6148
df3e68b1
HK
6149 Comp := First_Component (Typ);
6150 while Present (Comp) loop
6151 if Chars (Comp) = Name_uObject then
6152 return Base_Type (Etype (Comp));
6153 end if;
6154
6155 Next_Component (Comp);
6156 end loop;
6157
6158 -- The corresponding record of a protected type should always have an
6159 -- _object field.
6160
6161 raise Program_Error;
6162 end Find_Protection_Type;
6163
e59243fa
AC
6164 -----------------------
6165 -- Find_Hook_Context --
6166 -----------------------
6167
6168 function Find_Hook_Context (N : Node_Id) return Node_Id is
6169 Par : Node_Id;
6170 Top : Node_Id;
6171
6172 Wrapped_Node : Node_Id;
6173 -- Note: if we are in a transient scope, we want to reuse it as
6174 -- the context for actions insertion, if possible. But if N is itself
6175 -- part of the stored actions for the current transient scope,
6176 -- then we need to insert at the appropriate (inner) location in
6177 -- the not as an action on Node_To_Be_Wrapped.
6178
6179 In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N);
6180
6181 begin
6182 -- When the node is inside a case/if expression, the lifetime of any
6183 -- temporary controlled object is extended. Find a suitable insertion
6184 -- node by locating the topmost case or if expressions.
6185
6186 if In_Cond_Expr then
6187 Par := N;
6188 Top := N;
6189 while Present (Par) loop
4a08c95c
AC
6190 if Nkind (Original_Node (Par)) in
6191 N_Case_Expression | N_If_Expression
e59243fa
AC
6192 then
6193 Top := Par;
6194
6195 -- Prevent the search from going too far
6196
6197 elsif Is_Body_Or_Package_Declaration (Par) then
6198 exit;
6199 end if;
6200
6201 Par := Parent (Par);
6202 end loop;
6203
6204 -- The topmost case or if expression is now recovered, but it may
6205 -- still not be the correct place to add generated code. Climb to
6206 -- find a parent that is part of a declarative or statement list,
6207 -- and is not a list of actuals in a call.
6208
6209 Par := Top;
6210 while Present (Par) loop
6211 if Is_List_Member (Par)
4a08c95c
AC
6212 and then Nkind (Par) not in N_Component_Association
6213 | N_Discriminant_Association
6214 | N_Parameter_Association
6215 | N_Pragma_Argument_Association
6216 and then Nkind (Parent (Par)) not in N_Function_Call
6217 | N_Procedure_Call_Statement
6218 | N_Entry_Call_Statement
e59243fa
AC
6219
6220 then
6221 return Par;
6222
6223 -- Prevent the search from going too far
6224
6225 elsif Is_Body_Or_Package_Declaration (Par) then
6226 exit;
6227 end if;
6228
6229 Par := Parent (Par);
6230 end loop;
6231
6232 return Par;
6233
6234 else
6235 Par := N;
6236 while Present (Par) loop
6237
6238 -- Keep climbing past various operators
6239
6240 if Nkind (Parent (Par)) in N_Op
4a08c95c 6241 or else Nkind (Parent (Par)) in N_And_Then | N_Or_Else
e59243fa
AC
6242 then
6243 Par := Parent (Par);
6244 else
6245 exit;
6246 end if;
6247 end loop;
6248
6249 Top := Par;
6250
6251 -- The node may be located in a pragma in which case return the
6252 -- pragma itself:
6253
6254 -- pragma Precondition (... and then Ctrl_Func_Call ...);
6255
6256 -- Similar case occurs when the node is related to an object
6257 -- declaration or assignment:
6258
6259 -- Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...;
6260
6261 -- Another case to consider is when the node is part of a return
6262 -- statement:
6263
6264 -- return ... and then Ctrl_Func_Call ...;
6265
6266 -- Another case is when the node acts as a formal in a procedure
6267 -- call statement:
6268
6269 -- Proc (... and then Ctrl_Func_Call ...);
6270
6271 if Scope_Is_Transient then
6272 Wrapped_Node := Node_To_Be_Wrapped;
6273 else
6274 Wrapped_Node := Empty;
6275 end if;
6276
6277 while Present (Par) loop
6278 if Par = Wrapped_Node
4a08c95c
AC
6279 or else Nkind (Par) in N_Assignment_Statement
6280 | N_Object_Declaration
6281 | N_Pragma
6282 | N_Procedure_Call_Statement
6283 | N_Simple_Return_Statement
e59243fa
AC
6284 then
6285 return Par;
6286
6287 -- Prevent the search from going too far
6288
6289 elsif Is_Body_Or_Package_Declaration (Par) then
6290 exit;
6291 end if;
6292
6293 Par := Parent (Par);
6294 end loop;
6295
6296 -- Return the topmost short circuit operator
6297
6298 return Top;
6299 end if;
6300 end Find_Hook_Context;
6301
cd2c6027
AC
6302 ------------------------------
6303 -- Following_Address_Clause --
6304 ------------------------------
6305
cd2c6027 6306 function Following_Address_Clause (D : Node_Id) return Node_Id is
f2d9ae20
AC
6307 Id : constant Entity_Id := Defining_Identifier (D);
6308 Result : Node_Id;
6309 Par : Node_Id;
6310
6311 function Check_Decls (D : Node_Id) return Node_Id;
6312 -- This internal function differs from the main function in that it
6313 -- gets called to deal with a following package private part, and
6314 -- it checks declarations starting with D (the main function checks
6315 -- declarations following D). If D is Empty, then Empty is returned.
6316
6317 -----------------
6318 -- Check_Decls --
6319 -----------------
6320
6321 function Check_Decls (D : Node_Id) return Node_Id is
6322 Decl : Node_Id;
6323
6324 begin
6325 Decl := D;
6326 while Present (Decl) loop
6327 if Nkind (Decl) = N_At_Clause
6328 and then Chars (Identifier (Decl)) = Chars (Id)
6329 then
6330 return Decl;
6331
6332 elsif Nkind (Decl) = N_Attribute_Definition_Clause
6333 and then Chars (Decl) = Name_Address
6334 and then Chars (Name (Decl)) = Chars (Id)
6335 then
6336 return Decl;
6337 end if;
6338
6339 Next (Decl);
6340 end loop;
6341
6342 -- Otherwise not found, return Empty
6343
6344 return Empty;
6345 end Check_Decls;
6346
6347 -- Start of processing for Following_Address_Clause
cd2c6027
AC
6348
6349 begin
572f38e4 6350 -- If parser detected no address clause for the identifier in question,
de4ac038 6351 -- then the answer is a quick NO, without the need for a search.
572f38e4 6352
a921e83c 6353 if not Get_Name_Table_Boolean1 (Chars (Id)) then
572f38e4
AC
6354 return Empty;
6355 end if;
6356
6357 -- Otherwise search current declarative unit
6358
f2d9ae20 6359 Result := Check_Decls (Next (D));
cd2c6027 6360
f2d9ae20
AC
6361 if Present (Result) then
6362 return Result;
6363 end if;
cd2c6027 6364
f2d9ae20 6365 -- Check for possible package private part following
cd2c6027 6366
f2d9ae20
AC
6367 Par := Parent (D);
6368
6369 if Nkind (Par) = N_Package_Specification
6370 and then Visible_Declarations (Par) = List_Containing (D)
6371 and then Present (Private_Declarations (Par))
6372 then
6373 -- Private part present, check declarations there
6374
6375 return Check_Decls (First (Private_Declarations (Par)));
6376
6377 else
6378 -- No private part, clause not found, return Empty
6379
6380 return Empty;
6381 end if;
cd2c6027
AC
6382 end Following_Address_Clause;
6383
70482933
RK
6384 ----------------------
6385 -- Force_Evaluation --
6386 ----------------------
6387
28c7180f
RD
6388 procedure Force_Evaluation
6389 (Exp : Node_Id;
6390 Name_Req : Boolean := False;
6391 Related_Id : Entity_Id := Empty;
6392 Is_Low_Bound : Boolean := False;
89d3b1a1
AC
6393 Is_High_Bound : Boolean := False;
6394 Mode : Force_Evaluation_Mode := Relaxed)
28c7180f 6395 is
70482933 6396 begin
28c7180f 6397 Remove_Side_Effects
494a7e45
AC
6398 (Exp => Exp,
6399 Name_Req => Name_Req,
6400 Variable_Ref => True,
6401 Renaming_Req => False,
6402 Related_Id => Related_Id,
6403 Is_Low_Bound => Is_Low_Bound,
6404 Is_High_Bound => Is_High_Bound,
89d3b1a1
AC
6405 Check_Side_Effects =>
6406 Is_Static_Expression (Exp)
6407 or else Mode = Relaxed);
70482933
RK
6408 end Force_Evaluation;
6409
afbcdf5e
AC
6410 ---------------------------------
6411 -- Fully_Qualified_Name_String --
6412 ---------------------------------
6413
72267417
AC
6414 function Fully_Qualified_Name_String
6415 (E : Entity_Id;
6416 Append_NUL : Boolean := True) return String_Id
6417 is
afbcdf5e
AC
6418 procedure Internal_Full_Qualified_Name (E : Entity_Id);
6419 -- Compute recursively the qualified name without NUL at the end, adding
6420 -- it to the currently started string being generated
6421
6422 ----------------------------------
6423 -- Internal_Full_Qualified_Name --
6424 ----------------------------------
6425
6426 procedure Internal_Full_Qualified_Name (E : Entity_Id) is
6427 Ent : Entity_Id;
6428
6429 begin
6430 -- Deal properly with child units
6431
6432 if Nkind (E) = N_Defining_Program_Unit_Name then
6433 Ent := Defining_Identifier (E);
6434 else
6435 Ent := E;
6436 end if;
6437
6438 -- Compute qualification recursively (only "Standard" has no scope)
6439
6440 if Present (Scope (Scope (Ent))) then
6441 Internal_Full_Qualified_Name (Scope (Ent));
6442 Store_String_Char (Get_Char_Code ('.'));
6443 end if;
6444
6445 -- Every entity should have a name except some expanded blocks
6446 -- don't bother about those.
6447
6448 if Chars (Ent) = No_Name then
6449 return;
6450 end if;
6451
6452 -- Generates the entity name in upper case
6453
6454 Get_Decoded_Name_String (Chars (Ent));
6455 Set_All_Upper_Case;
6456 Store_String_Chars (Name_Buffer (1 .. Name_Len));
6457 return;
6458 end Internal_Full_Qualified_Name;
6459
6460 -- Start of processing for Full_Qualified_Name
6461
6462 begin
6463 Start_String;
6464 Internal_Full_Qualified_Name (E);
9d5598bf 6465
72267417
AC
6466 if Append_NUL then
6467 Store_String_Char (Get_Char_Code (ASCII.NUL));
6468 end if;
9d5598bf 6469
afbcdf5e
AC
6470 return End_String;
6471 end Fully_Qualified_Name_String;
6472
fbf5a39b
AC
6473 ---------------------------------
6474 -- Get_Current_Value_Condition --
6475 ---------------------------------
6476
05350ac6
BD
6477 -- Note: the implementation of this procedure is very closely tied to the
6478 -- implementation of Set_Current_Value_Condition. In the Get procedure, we
6479 -- interpret Current_Value fields set by the Set procedure, so the two
6480 -- procedures need to be closely coordinated.
6481
fbf5a39b
AC
6482 procedure Get_Current_Value_Condition
6483 (Var : Node_Id;
6484 Op : out Node_Kind;
6485 Val : out Node_Id)
6486 is
59e54267
ES
6487 Loc : constant Source_Ptr := Sloc (Var);
6488 Ent : constant Entity_Id := Entity (Var);
fbf5a39b 6489
b9348660 6490 procedure Process_Current_Value_Condition (N : Node_Id; S : Boolean);
05350ac6
BD
6491 -- N is an expression which holds either True (S = True) or False (S =
6492 -- False) in the condition. This procedure digs out the expression and
6493 -- if it refers to Ent, sets Op and Val appropriately.
6494
6495 -------------------------------------
6496 -- Process_Current_Value_Condition --
6497 -------------------------------------
6498
6499 procedure Process_Current_Value_Condition
6500 (N : Node_Id;
6501 S : Boolean)
6502 is
064f4527
TQ
6503 Cond : Node_Id;
6504 Prev_Cond : Node_Id;
6505 Sens : Boolean;
05350ac6
BD
6506
6507 begin
6508 Cond := N;
6509 Sens := S;
6510
064f4527
TQ
6511 loop
6512 Prev_Cond := Cond;
05350ac6 6513
064f4527
TQ
6514 -- Deal with NOT operators, inverting sense
6515
6516 while Nkind (Cond) = N_Op_Not loop
6517 Cond := Right_Opnd (Cond);
6518 Sens := not Sens;
6519 end loop;
6520
6521 -- Deal with conversions, qualifications, and expressions with
6522 -- actions.
6523
4a08c95c
AC
6524 while Nkind (Cond) in N_Type_Conversion
6525 | N_Qualified_Expression
6526 | N_Expression_With_Actions
064f4527
TQ
6527 loop
6528 Cond := Expression (Cond);
6529 end loop;
6530
6531 exit when Cond = Prev_Cond;
05350ac6
BD
6532 end loop;
6533
6534 -- Deal with AND THEN and AND cases
6535
4a08c95c 6536 if Nkind (Cond) in N_And_Then | N_Op_And then
0e564ab4 6537
aa9a7dd7
AC
6538 -- Don't ever try to invert a condition that is of the form of an
6539 -- AND or AND THEN (since we are not doing sufficiently general
6540 -- processing to allow this).
05350ac6
BD
6541
6542 if Sens = False then
6543 Op := N_Empty;
6544 Val := Empty;
6545 return;
6546 end if;
6547
6548 -- Recursively process AND and AND THEN branches
6549
6550 Process_Current_Value_Condition (Left_Opnd (Cond), True);
b9348660 6551 pragma Assert (Op'Valid);
05350ac6
BD
6552
6553 if Op /= N_Empty then
6554 return;
6555 end if;
6556
6557 Process_Current_Value_Condition (Right_Opnd (Cond), True);
6558 return;
6559
6560 -- Case of relational operator
6561
6562 elsif Nkind (Cond) in N_Op_Compare then
6563 Op := Nkind (Cond);
6564
6565 -- Invert sense of test if inverted test
6566
6567 if Sens = False then
6568 case Op is
6569 when N_Op_Eq => Op := N_Op_Ne;
6570 when N_Op_Ne => Op := N_Op_Eq;
6571 when N_Op_Lt => Op := N_Op_Ge;
6572 when N_Op_Gt => Op := N_Op_Le;
6573 when N_Op_Le => Op := N_Op_Gt;
6574 when N_Op_Ge => Op := N_Op_Lt;
6575 when others => raise Program_Error;
6576 end case;
6577 end if;
6578
6579 -- Case of entity op value
6580
6581 if Is_Entity_Name (Left_Opnd (Cond))
6582 and then Ent = Entity (Left_Opnd (Cond))
6583 and then Compile_Time_Known_Value (Right_Opnd (Cond))
6584 then
6585 Val := Right_Opnd (Cond);
6586
6587 -- Case of value op entity
6588
6589 elsif Is_Entity_Name (Right_Opnd (Cond))
6590 and then Ent = Entity (Right_Opnd (Cond))
6591 and then Compile_Time_Known_Value (Left_Opnd (Cond))
6592 then
6593 Val := Left_Opnd (Cond);
6594
6595 -- We are effectively swapping operands
6596
6597 case Op is
6598 when N_Op_Eq => null;
6599 when N_Op_Ne => null;
6600 when N_Op_Lt => Op := N_Op_Gt;
6601 when N_Op_Gt => Op := N_Op_Lt;
6602 when N_Op_Le => Op := N_Op_Ge;
6603 when N_Op_Ge => Op := N_Op_Le;
6604 when others => raise Program_Error;
6605 end case;
6606
6607 else
6608 Op := N_Empty;
6609 end if;
6610
6611 return;
6612
4a08c95c
AC
6613 elsif Nkind (Cond) in N_Type_Conversion
6614 | N_Qualified_Expression
6615 | N_Expression_With_Actions
064f4527
TQ
6616 then
6617 Cond := Expression (Cond);
6618
6619 -- Case of Boolean variable reference, return as though the
6620 -- reference had said var = True.
05350ac6
BD
6621
6622 else
0e564ab4 6623 if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then
05350ac6
BD
6624 Val := New_Occurrence_Of (Standard_True, Sloc (Cond));
6625
6626 if Sens = False then
6627 Op := N_Op_Ne;
6628 else
6629 Op := N_Op_Eq;
6630 end if;
6631 end if;
6632 end if;
6633 end Process_Current_Value_Condition;
6634
6635 -- Start of processing for Get_Current_Value_Condition
6636
fbf5a39b
AC
6637 begin
6638 Op := N_Empty;
6639 Val := Empty;
6640
59e54267 6641 -- Immediate return, nothing doing, if this is not an object
fbf5a39b 6642
a1447c2a 6643 if not Is_Object (Ent) then
59e54267
ES
6644 return;
6645 end if;
fbf5a39b 6646
97847797
PT
6647 -- In GNATprove mode we don't want to use current value optimizer, in
6648 -- particular for loop invariant expressions and other assertions that
6649 -- act as cut points for proof. The optimizer often folds expressions
6650 -- into True/False where they trivially follow from the previous
6651 -- assignments, but this deprives proof from the information needed to
6652 -- discharge checks that are beyond the scope of the value optimizer.
6653
6654 if GNATprove_Mode then
6655 return;
6656 end if;
6657
59e54267 6658 -- Otherwise examine current value
fbf5a39b 6659
59e54267
ES
6660 declare
6661 CV : constant Node_Id := Current_Value (Ent);
6662 Sens : Boolean;
6663 Stm : Node_Id;
fbf5a39b 6664
59e54267
ES
6665 begin
6666 -- If statement. Condition is known true in THEN section, known False
6667 -- in any ELSIF or ELSE part, and unknown outside the IF statement.
fbf5a39b 6668
59e54267 6669 if Nkind (CV) = N_If_Statement then
fbf5a39b 6670
59e54267 6671 -- Before start of IF statement
fbf5a39b 6672
59e54267
ES
6673 if Loc < Sloc (CV) then
6674 return;
fbf5a39b 6675
8e334288 6676 -- After end of IF statement
fbf5a39b 6677
59e54267
ES
6678 elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then
6679 return;
6680 end if;
fbf5a39b 6681
59e54267
ES
6682 -- At this stage we know that we are within the IF statement, but
6683 -- unfortunately, the tree does not record the SLOC of the ELSE so
6684 -- we cannot use a simple SLOC comparison to distinguish between
6685 -- the then/else statements, so we have to climb the tree.
fbf5a39b 6686
59e54267
ES
6687 declare
6688 N : Node_Id;
fbf5a39b 6689
59e54267
ES
6690 begin
6691 N := Parent (Var);
6692 while Parent (N) /= CV loop
6693 N := Parent (N);
fbf5a39b 6694
59e54267
ES
6695 -- If we fall off the top of the tree, then that's odd, but
6696 -- perhaps it could occur in some error situation, and the
6697 -- safest response is simply to assume that the outcome of
6698 -- the condition is unknown. No point in bombing during an
6699 -- attempt to optimize things.
fbf5a39b 6700
59e54267
ES
6701 if No (N) then
6702 return;
6703 end if;
6704 end loop;
fbf5a39b 6705
59e54267
ES
6706 -- Now we have N pointing to a node whose parent is the IF
6707 -- statement in question, so now we can tell if we are within
6708 -- the THEN statements.
fbf5a39b 6709
59e54267
ES
6710 if Is_List_Member (N)
6711 and then List_Containing (N) = Then_Statements (CV)
6712 then
6713 Sens := True;
fbf5a39b 6714
05350ac6
BD
6715 -- If the variable reference does not come from source, we
6716 -- cannot reliably tell whether it appears in the else part.
16b05213 6717 -- In particular, if it appears in generated code for a node
05350ac6
BD
6718 -- that requires finalization, it may be attached to a list
6719 -- that has not been yet inserted into the code. For now,
6720 -- treat it as unknown.
6721
6722 elsif not Comes_From_Source (N) then
6723 return;
6724
6725 -- Otherwise we must be in ELSIF or ELSE part
fbf5a39b 6726
59e54267
ES
6727 else
6728 Sens := False;
6729 end if;
6730 end;
fbf5a39b 6731
59e54267 6732 -- ELSIF part. Condition is known true within the referenced
aa9a7dd7
AC
6733 -- ELSIF, known False in any subsequent ELSIF or ELSE part,
6734 -- and unknown before the ELSE part or after the IF statement.
fbf5a39b 6735
59e54267 6736 elsif Nkind (CV) = N_Elsif_Part then
196379c6
ES
6737
6738 -- if the Elsif_Part had condition_actions, the elsif has been
6739 -- rewritten as a nested if, and the original elsif_part is
6740 -- detached from the tree, so there is no way to obtain useful
6741 -- information on the current value of the variable.
6742 -- Can this be improved ???
6743
6744 if No (Parent (CV)) then
6745 return;
6746 end if;
6747
59e54267 6748 Stm := Parent (CV);
fbf5a39b 6749
a0a10853
AC
6750 -- If the tree has been otherwise rewritten there is nothing
6751 -- else to be done either.
6752
6753 if Nkind (Stm) /= N_If_Statement then
6754 return;
6755 end if;
6756
59e54267 6757 -- Before start of ELSIF part
fbf5a39b 6758
59e54267
ES
6759 if Loc < Sloc (CV) then
6760 return;
fbf5a39b 6761
59e54267 6762 -- After end of IF statement
fbf5a39b 6763
59e54267
ES
6764 elsif Loc >= Sloc (Stm) +
6765 Text_Ptr (UI_To_Int (End_Span (Stm)))
6766 then
6767 return;
6768 end if;
fbf5a39b 6769
59e54267
ES
6770 -- Again we lack the SLOC of the ELSE, so we need to climb the
6771 -- tree to see if we are within the ELSIF part in question.
fbf5a39b 6772
59e54267
ES
6773 declare
6774 N : Node_Id;
fbf5a39b 6775
59e54267
ES
6776 begin
6777 N := Parent (Var);
6778 while Parent (N) /= Stm loop
6779 N := Parent (N);
fbf5a39b 6780
59e54267
ES
6781 -- If we fall off the top of the tree, then that's odd, but
6782 -- perhaps it could occur in some error situation, and the
6783 -- safest response is simply to assume that the outcome of
6784 -- the condition is unknown. No point in bombing during an
6785 -- attempt to optimize things.
fbf5a39b 6786
59e54267
ES
6787 if No (N) then
6788 return;
6789 end if;
6790 end loop;
fbf5a39b 6791
59e54267
ES
6792 -- Now we have N pointing to a node whose parent is the IF
6793 -- statement in question, so see if is the ELSIF part we want.
6794 -- the THEN statements.
fbf5a39b 6795
59e54267
ES
6796 if N = CV then
6797 Sens := True;
fbf5a39b 6798
e14c931f 6799 -- Otherwise we must be in subsequent ELSIF or ELSE part
fbf5a39b 6800
59e54267
ES
6801 else
6802 Sens := False;
6803 end if;
6804 end;
fbf5a39b 6805
05350ac6
BD
6806 -- Iteration scheme of while loop. The condition is known to be
6807 -- true within the body of the loop.
59e54267 6808
05350ac6
BD
6809 elsif Nkind (CV) = N_Iteration_Scheme then
6810 declare
6811 Loop_Stmt : constant Node_Id := Parent (CV);
fbf5a39b 6812
05350ac6
BD
6813 begin
6814 -- Before start of body of loop
fbf5a39b 6815
05350ac6
BD
6816 if Loc < Sloc (Loop_Stmt) then
6817 return;
fbf5a39b 6818
05350ac6 6819 -- After end of LOOP statement
59e54267 6820
05350ac6
BD
6821 elsif Loc >= Sloc (End_Label (Loop_Stmt)) then
6822 return;
59e54267 6823
05350ac6 6824 -- We are within the body of the loop
59e54267 6825
05350ac6
BD
6826 else
6827 Sens := True;
6828 end if;
6829 end;
fbf5a39b 6830
05350ac6 6831 -- All other cases of Current_Value settings
fbf5a39b 6832
05350ac6
BD
6833 else
6834 return;
59e54267 6835 end if;
05350ac6
BD
6836
6837 -- If we fall through here, then we have a reportable condition, Sens
6838 -- is True if the condition is true and False if it needs inverting.
6839
6840 Process_Current_Value_Condition (Condition (CV), Sens);
59e54267 6841 end;
fbf5a39b
AC
6842 end Get_Current_Value_Condition;
6843
3ebf0cbd
PT
6844 -----------------------
6845 -- Get_Index_Subtype --
6846 -----------------------
6847
6848 function Get_Index_Subtype (N : Node_Id) return Node_Id is
6849 P_Type : Entity_Id := Etype (Prefix (N));
6850 Indx : Node_Id;
6851 J : Int;
6852
6853 begin
6854 if Is_Access_Type (P_Type) then
6855 P_Type := Designated_Type (P_Type);
6856 end if;
6857
6858 if No (Expressions (N)) then
6859 J := 1;
6860 else
6861 J := UI_To_Int (Expr_Value (First (Expressions (N))));
6862 end if;
6863
6864 Indx := First_Index (P_Type);
6865 while J > 1 loop
6866 Next_Index (Indx);
6867 J := J - 1;
6868 end loop;
6869
6870 return Etype (Indx);
6871 end Get_Index_Subtype;
6872
9eea4346
GB
6873 ---------------------
6874 -- Get_Stream_Size --
6875 ---------------------
6876
6877 function Get_Stream_Size (E : Entity_Id) return Uint is
6878 begin
6879 -- If we have a Stream_Size clause for this type use it
6880
6881 if Has_Stream_Size_Clause (E) then
6882 return Static_Integer (Expression (Stream_Size_Clause (E)));
6883
90cb252f 6884 -- Otherwise the Stream_Size is the size of the type
9eea4346
GB
6885
6886 else
6887 return Esize (E);
6888 end if;
6889 end Get_Stream_Size;
6890
df3e68b1
HK
6891 ---------------------------
6892 -- Has_Access_Constraint --
6893 ---------------------------
6894
6895 function Has_Access_Constraint (E : Entity_Id) return Boolean is
6896 Disc : Entity_Id;
6897 T : constant Entity_Id := Etype (E);
6898
6899 begin
0e564ab4 6900 if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then
df3e68b1
HK
6901 Disc := First_Discriminant (T);
6902 while Present (Disc) loop
6903 if Is_Access_Type (Etype (Disc)) then
6904 return True;
6905 end if;
6906
6907 Next_Discriminant (Disc);
6908 end loop;
6909
6910 return False;
6911 else
6912 return False;
6913 end if;
6914 end Has_Access_Constraint;
6915
70482933
RK
6916 --------------------
6917 -- Homonym_Number --
6918 --------------------
6919
c4f372c5
PT
6920 function Homonym_Number (Subp : Entity_Id) return Pos is
6921 Hom : Entity_Id := Homonym (Subp);
6922 Count : Pos := 1;
70482933
RK
6923
6924 begin
70482933
RK
6925 while Present (Hom) loop
6926 if Scope (Hom) = Scope (Subp) then
6927 Count := Count + 1;
6928 end if;
6929
6930 Hom := Homonym (Hom);
6931 end loop;
6932
6933 return Count;
6934 end Homonym_Number;
6935
df3e68b1
HK
6936 -----------------------------------
6937 -- In_Library_Level_Package_Body --
6938 -----------------------------------
6939
6940 function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is
6941 begin
6942 -- First determine whether the entity appears at the library level, then
6943 -- look at the containing unit.
6944
6945 if Is_Library_Level_Entity (Id) then
6946 declare
6947 Container : constant Node_Id := Cunit (Get_Source_Unit (Id));
6948
6949 begin
6950 return Nkind (Unit (Container)) = N_Package_Body;
6951 end;
6952 end if;
6953
6954 return False;
6955 end In_Library_Level_Package_Body;
6956
70482933
RK
6957 ------------------------------
6958 -- In_Unconditional_Context --
6959 ------------------------------
6960
6961 function In_Unconditional_Context (Node : Node_Id) return Boolean is
6962 P : Node_Id;
6963
6964 begin
6965 P := Node;
6966 while Present (P) loop
6967 case Nkind (P) is
d8f43ee6
HK
6968 when N_Subprogram_Body => return True;
6969 when N_If_Statement => return False;
6970 when N_Loop_Statement => return False;
6971 when N_Case_Statement => return False;
6972 when others => P := Parent (P);
70482933
RK
6973 end case;
6974 end loop;
6975
6976 return False;
6977 end In_Unconditional_Context;
6978
6979 -------------------
6980 -- Insert_Action --
6981 -------------------
6982
e2819941
HK
6983 procedure Insert_Action
6984 (Assoc_Node : Node_Id;
6985 Ins_Action : Node_Id;
6986 Spec_Expr_OK : Boolean := False)
6987 is
70482933
RK
6988 begin
6989 if Present (Ins_Action) then
e2819941
HK
6990 Insert_Actions
6991 (Assoc_Node => Assoc_Node,
6992 Ins_Actions => New_List (Ins_Action),
6993 Spec_Expr_OK => Spec_Expr_OK);
70482933
RK
6994 end if;
6995 end Insert_Action;
6996
6997 -- Version with check(s) suppressed
6998
6999 procedure Insert_Action
e2819941
HK
7000 (Assoc_Node : Node_Id;
7001 Ins_Action : Node_Id;
7002 Suppress : Check_Id;
7003 Spec_Expr_OK : Boolean := False)
70482933
RK
7004 is
7005 begin
e2819941
HK
7006 Insert_Actions
7007 (Assoc_Node => Assoc_Node,
7008 Ins_Actions => New_List (Ins_Action),
7009 Suppress => Suppress,
7010 Spec_Expr_OK => Spec_Expr_OK);
70482933
RK
7011 end Insert_Action;
7012
df3e68b1
HK
7013 -------------------------
7014 -- Insert_Action_After --
7015 -------------------------
7016
7017 procedure Insert_Action_After
7018 (Assoc_Node : Node_Id;
7019 Ins_Action : Node_Id)
7020 is
7021 begin
7022 Insert_Actions_After (Assoc_Node, New_List (Ins_Action));
7023 end Insert_Action_After;
7024
70482933
RK
7025 --------------------
7026 -- Insert_Actions --
7027 --------------------
7028
e2819941
HK
7029 procedure Insert_Actions
7030 (Assoc_Node : Node_Id;
7031 Ins_Actions : List_Id;
7032 Spec_Expr_OK : Boolean := False)
7033 is
70482933
RK
7034 N : Node_Id;
7035 P : Node_Id;
7036
7037 Wrapped_Node : Node_Id := Empty;
7038
7039 begin
7040 if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then
7041 return;
7042 end if;
7043
e2819941
HK
7044 -- Insert the action when the context is "Handling of Default and Per-
7045 -- Object Expressions" only when requested by the caller.
7046
7047 if Spec_Expr_OK then
7048 null;
7049
65df5b71
HK
7050 -- Ignore insert of actions from inside default expression (or other
7051 -- similar "spec expression") in the special spec-expression analyze
7052 -- mode. Any insertions at this point have no relevance, since we are
7053 -- only doing the analyze to freeze the types of any static expressions.
e2819941
HK
7054 -- See section "Handling of Default and Per-Object Expressions" in the
7055 -- spec of package Sem for further details.
70482933 7056
e2819941 7057 elsif In_Spec_Expression then
70482933
RK
7058 return;
7059 end if;
7060
7061 -- If the action derives from stuff inside a record, then the actions
7062 -- are attached to the current scope, to be inserted and analyzed on
273adcdf
AC
7063 -- exit from the scope. The reason for this is that we may also be
7064 -- generating freeze actions at the same time, and they must eventually
7065 -- be elaborated in the correct order.
70482933
RK
7066
7067 if Is_Record_Type (Current_Scope)
7068 and then not Is_Frozen (Current_Scope)
7069 then
7070 if No (Scope_Stack.Table
7fcd29e0 7071 (Scope_Stack.Last).Pending_Freeze_Actions)
70482933
RK
7072 then
7073 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions :=
7074 Ins_Actions;
7075 else
7076 Append_List
7077 (Ins_Actions,
7078 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions);
7079 end if;
7080
7081 return;
7082 end if;
7083
7084 -- We now intend to climb up the tree to find the right point to
273adcdf
AC
7085 -- insert the actions. We start at Assoc_Node, unless this node is a
7086 -- subexpression in which case we start with its parent. We do this for
7087 -- two reasons. First it speeds things up. Second, if Assoc_Node is
7088 -- itself one of the special nodes like N_And_Then, then we assume that
7089 -- an initial request to insert actions for such a node does not expect
7090 -- the actions to get deposited in the node for later handling when the
7091 -- node is expanded, since clearly the node is being dealt with by the
7092 -- caller. Note that in the subexpression case, N is always the child we
7093 -- came from.
7094
9bdc432a
AC
7095 -- N_Raise_xxx_Error is an annoying special case, it is a statement
7096 -- if it has type Standard_Void_Type, and a subexpression otherwise.
7097 -- Procedure calls, and similarly procedure attribute references, are
7098 -- also statements.
70482933
RK
7099
7100 if Nkind (Assoc_Node) in N_Subexpr
a52e6d7e 7101 and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error
70482933 7102 or else Etype (Assoc_Node) /= Standard_Void_Type)
a52e6d7e 7103 and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement
70482933 7104 and then (Nkind (Assoc_Node) /= N_Attribute_Reference
c5c780e6
HK
7105 or else not Is_Procedure_Attribute_Name
7106 (Attribute_Name (Assoc_Node)))
70482933 7107 then
a52e6d7e
AC
7108 N := Assoc_Node;
7109 P := Parent (Assoc_Node);
70482933 7110
3f833dc2
GD
7111 -- Nonsubexpression case. Note that N is initially Empty in this case
7112 -- (N is only guaranteed non-Empty in the subexpr case).
70482933
RK
7113
7114 else
70482933 7115 N := Empty;
a52e6d7e 7116 P := Assoc_Node;
70482933
RK
7117 end if;
7118
7119 -- Capture root of the transient scope
7120
7121 if Scope_Is_Transient then
05350ac6 7122 Wrapped_Node := Node_To_Be_Wrapped;
70482933
RK
7123 end if;
7124
7125 loop
7126 pragma Assert (Present (P));
7127
a52e6d7e
AC
7128 -- Make sure that inserted actions stay in the transient scope
7129
7130 if Present (Wrapped_Node) and then N = Wrapped_Node then
7131 Store_Before_Actions_In_Scope (Ins_Actions);
7132 return;
7133 end if;
7134
70482933
RK
7135 case Nkind (P) is
7136
7137 -- Case of right operand of AND THEN or OR ELSE. Put the actions
7138 -- in the Actions field of the right operand. They will be moved
7139 -- out further when the AND THEN or OR ELSE operator is expanded.
7140 -- Nothing special needs to be done for the left operand since
7141 -- in that case the actions are executed unconditionally.
7142
ac7120ce 7143 when N_Short_Circuit =>
70482933 7144 if N = Right_Opnd (P) then
ac4d6407
RD
7145
7146 -- We are now going to either append the actions to the
7147 -- actions field of the short-circuit operation. We will
7148 -- also analyze the actions now.
7149
7150 -- This analysis is really too early, the proper thing would
7151 -- be to just park them there now, and only analyze them if
7152 -- we find we really need them, and to it at the proper
7153 -- final insertion point. However attempting to this proved
7154 -- tricky, so for now we just kill current values before and
7155 -- after the analyze call to make sure we avoid peculiar
7156 -- optimizations from this out of order insertion.
7157
7158 Kill_Current_Values;
7159
2e70d415
AC
7160 -- If P has already been expanded, we can't park new actions
7161 -- on it, so we need to expand them immediately, introducing
7162 -- an Expression_With_Actions. N can't be an expression
7163 -- with actions, or else then the actions would have been
7164 -- inserted at an inner level.
7165
7166 if Analyzed (P) then
7167 pragma Assert (Nkind (N) /= N_Expression_With_Actions);
7168 Rewrite (N,
7169 Make_Expression_With_Actions (Sloc (N),
7170 Actions => Ins_Actions,
7171 Expression => Relocate_Node (N)));
7172 Analyze_And_Resolve (N);
7173
7174 elsif Present (Actions (P)) then
70482933 7175 Insert_List_After_And_Analyze
ac4d6407 7176 (Last (Actions (P)), Ins_Actions);
70482933
RK
7177 else
7178 Set_Actions (P, Ins_Actions);
7179 Analyze_List (Actions (P));
7180 end if;
7181
ac4d6407
RD
7182 Kill_Current_Values;
7183
70482933
RK
7184 return;
7185 end if;
7186
9b16cb57
RD
7187 -- Then or Else dependent expression of an if expression. Add
7188 -- actions to Then_Actions or Else_Actions field as appropriate.
7189 -- The actions will be moved further out when the if is expanded.
70482933 7190
9b16cb57 7191 when N_If_Expression =>
70482933
RK
7192 declare
7193 ThenX : constant Node_Id := Next (First (Expressions (P)));
7194 ElseX : constant Node_Id := Next (ThenX);
7195
7196 begin
aa9a7dd7
AC
7197 -- If the enclosing expression is already analyzed, as
7198 -- is the case for nested elaboration checks, insert the
7199 -- conditional further out.
70482933 7200
aa9a7dd7
AC
7201 if Analyzed (P) then
7202 null;
7203
7204 -- Actions belong to the then expression, temporarily place
9b16cb57
RD
7205 -- them as Then_Actions of the if expression. They will be
7206 -- moved to the proper place later when the if expression
7207 -- is expanded.
aa9a7dd7
AC
7208
7209 elsif N = ThenX then
70482933
RK
7210 if Present (Then_Actions (P)) then
7211 Insert_List_After_And_Analyze
7212 (Last (Then_Actions (P)), Ins_Actions);
7213 else
7214 Set_Then_Actions (P, Ins_Actions);
7215 Analyze_List (Then_Actions (P));
7216 end if;
7217
7218 return;
7219
9b16cb57
RD
7220 -- Actions belong to the else expression, temporarily place
7221 -- them as Else_Actions of the if expression. They will be
7222 -- moved to the proper place later when the if expression
7223 -- is expanded.
70482933
RK
7224
7225 elsif N = ElseX then
7226 if Present (Else_Actions (P)) then
7227 Insert_List_After_And_Analyze
7228 (Last (Else_Actions (P)), Ins_Actions);
7229 else
7230 Set_Else_Actions (P, Ins_Actions);
7231 Analyze_List (Else_Actions (P));
7232 end if;
7233
7234 return;
7235
7236 -- Actions belong to the condition. In this case they are
7237 -- unconditionally executed, and so we can continue the
7238 -- search for the proper insert point.
7239
7240 else
7241 null;
7242 end if;
7243 end;
7244
aa9a7dd7
AC
7245 -- Alternative of case expression, we place the action in the
7246 -- Actions field of the case expression alternative, this will
7247 -- be handled when the case expression is expanded.
19d846a0
RD
7248
7249 when N_Case_Expression_Alternative =>
7250 if Present (Actions (P)) then
7251 Insert_List_After_And_Analyze
7252 (Last (Actions (P)), Ins_Actions);
7253 else
7254 Set_Actions (P, Ins_Actions);
1c54829e 7255 Analyze_List (Actions (P));
19d846a0
RD
7256 end if;
7257
7258 return;
7259
a52e6d7e
AC
7260 -- Case of appearing within an Expressions_With_Actions node. When
7261 -- the new actions come from the expression of the expression with
7262 -- actions, they must be added to the existing actions. The other
7263 -- alternative is when the new actions are related to one of the
2e70d415 7264 -- existing actions of the expression with actions, and should
f5f6d8d7
AC
7265 -- never reach here: if actions are inserted on a statement
7266 -- within the Actions of an expression with actions, or on some
cd5acda5 7267 -- subexpression of such a statement, then the outermost proper
2e70d415
AC
7268 -- insertion point is right before the statement, and we should
7269 -- never climb up as far as the N_Expression_With_Actions itself.
955871d3
AC
7270
7271 when N_Expression_With_Actions =>
a52e6d7e 7272 if N = Expression (P) then
064f4527
TQ
7273 if Is_Empty_List (Actions (P)) then
7274 Append_List_To (Actions (P), Ins_Actions);
7275 Analyze_List (Actions (P));
7276 else
7277 Insert_List_After_And_Analyze
7278 (Last (Actions (P)), Ins_Actions);
7279 end if;
f5f6d8d7 7280
72e9f2b9 7281 return;
2e70d415
AC
7282
7283 else
7284 raise Program_Error;
72e9f2b9 7285 end if;
955871d3 7286
70482933
RK
7287 -- Case of appearing in the condition of a while expression or
7288 -- elsif. We insert the actions into the Condition_Actions field.
7289 -- They will be moved further out when the while loop or elsif
7290 -- is analyzed.
7291
d8f43ee6
HK
7292 when N_Elsif_Part
7293 | N_Iteration_Scheme
70482933
RK
7294 =>
7295 if N = Condition (P) then
7296 if Present (Condition_Actions (P)) then
7297 Insert_List_After_And_Analyze
7298 (Last (Condition_Actions (P)), Ins_Actions);
7299 else
7300 Set_Condition_Actions (P, Ins_Actions);
7301
aa9a7dd7
AC
7302 -- Set the parent of the insert actions explicitly. This
7303 -- is not a syntactic field, but we need the parent field
7304 -- set, in particular so that freeze can understand that
7305 -- it is dealing with condition actions, and properly
7306 -- insert the freezing actions.
70482933
RK
7307
7308 Set_Parent (Ins_Actions, P);
7309 Analyze_List (Condition_Actions (P));
7310 end if;
7311
7312 return;
7313 end if;
7314
bebbff91 7315 -- Statements, declarations, pragmas, representation clauses
70482933
RK
7316
7317 when
7318 -- Statements
7319
d8f43ee6
HK
7320 N_Procedure_Call_Statement
7321 | N_Statement_Other_Than_Procedure_Call
70482933
RK
7322
7323 -- Pragmas
7324
d8f43ee6 7325 | N_Pragma
70482933
RK
7326
7327 -- Representation_Clause
7328
d8f43ee6
HK
7329 | N_At_Clause
7330 | N_Attribute_Definition_Clause
7331 | N_Enumeration_Representation_Clause
7332 | N_Record_Representation_Clause
70482933
RK
7333
7334 -- Declarations
7335
d8f43ee6
HK
7336 | N_Abstract_Subprogram_Declaration
7337 | N_Entry_Body
7338 | N_Exception_Declaration
7339 | N_Exception_Renaming_Declaration
7340 | N_Expression_Function
7341 | N_Formal_Abstract_Subprogram_Declaration
7342 | N_Formal_Concrete_Subprogram_Declaration
7343 | N_Formal_Object_Declaration
7344 | N_Formal_Type_Declaration
7345 | N_Full_Type_Declaration
7346 | N_Function_Instantiation
7347 | N_Generic_Function_Renaming_Declaration
7348 | N_Generic_Package_Declaration
7349 | N_Generic_Package_Renaming_Declaration
7350 | N_Generic_Procedure_Renaming_Declaration
7351 | N_Generic_Subprogram_Declaration
7352 | N_Implicit_Label_Declaration
7353 | N_Incomplete_Type_Declaration
7354 | N_Number_Declaration
7355 | N_Object_Declaration
7356 | N_Object_Renaming_Declaration
7357 | N_Package_Body
7358 | N_Package_Body_Stub
7359 | N_Package_Declaration
7360 | N_Package_Instantiation
7361 | N_Package_Renaming_Declaration
7362 | N_Private_Extension_Declaration
7363 | N_Private_Type_Declaration
7364 | N_Procedure_Instantiation
7365 | N_Protected_Body
7366 | N_Protected_Body_Stub
d8f43ee6
HK
7367 | N_Single_Task_Declaration
7368 | N_Subprogram_Body
7369 | N_Subprogram_Body_Stub
7370 | N_Subprogram_Declaration
7371 | N_Subprogram_Renaming_Declaration
7372 | N_Subtype_Declaration
7373 | N_Task_Body
7374 | N_Task_Body_Stub
70482933 7375
8c889ae4
AC
7376 -- Use clauses can appear in lists of declarations
7377
d8f43ee6
HK
7378 | N_Use_Package_Clause
7379 | N_Use_Type_Clause
8c889ae4 7380
70482933
RK
7381 -- Freeze entity behaves like a declaration or statement
7382
d8f43ee6
HK
7383 | N_Freeze_Entity
7384 | N_Freeze_Generic_Entity
70482933
RK
7385 =>
7386 -- Do not insert here if the item is not a list member (this
7387 -- happens for example with a triggering statement, and the
7388 -- proper approach is to insert before the entire select).
7389
7390 if not Is_List_Member (P) then
7391 null;
7392
7393 -- Do not insert if parent of P is an N_Component_Association
05350ac6
BD
7394 -- node (i.e. we are in the context of an N_Aggregate or
7395 -- N_Extension_Aggregate node. In this case we want to insert
7396 -- before the entire aggregate.
70482933
RK
7397
7398 elsif Nkind (Parent (P)) = N_Component_Association then
7399 null;
7400
273adcdf
AC
7401 -- Do not insert if the parent of P is either an N_Variant node
7402 -- or an N_Record_Definition node, meaning in either case that
7403 -- P is a member of a component list, and that therefore the
7404 -- actions should be inserted outside the complete record
7405 -- declaration.
70482933 7406
4a08c95c 7407 elsif Nkind (Parent (P)) in N_Variant | N_Record_Definition then
70482933
RK
7408 null;
7409
7410 -- Do not insert freeze nodes within the loop generated for
7411 -- an aggregate, because they may be elaborated too late for
7412 -- subsequent use in the back end: within a package spec the
7413 -- loop is part of the elaboration procedure and is only
7414 -- elaborated during the second pass.
aa9a7dd7 7415
273adcdf
AC
7416 -- If the loop comes from source, or the entity is local to the
7417 -- loop itself it must remain within.
70482933
RK
7418
7419 elsif Nkind (Parent (P)) = N_Loop_Statement
7420 and then not Comes_From_Source (Parent (P))
7421 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity
7422 and then
7423 Scope (Entity (First (Ins_Actions))) /= Current_Scope
7424 then
7425 null;
7426
7427 -- Otherwise we can go ahead and do the insertion
7428
05350ac6 7429 elsif P = Wrapped_Node then
70482933
RK
7430 Store_Before_Actions_In_Scope (Ins_Actions);
7431 return;
7432
7433 else
7434 Insert_List_Before_And_Analyze (P, Ins_Actions);
7435 return;
7436 end if;
7437
076bbec1
ES
7438 -- the expansion of Task and protected type declarations can
7439 -- create declarations for temporaries which, like other actions
7440 -- are inserted and analyzed before the current declaraation.
7441 -- However, the current scope is the synchronized type, and
7442 -- for unnesting it is critical that the proper scope for these
7443 -- generated entities be the enclosing one.
7444
7445 when N_Task_Type_Declaration
7446 | N_Protected_Type_Declaration =>
7447
7448 Push_Scope (Scope (Current_Scope));
7449 Insert_List_Before_And_Analyze (P, Ins_Actions);
7450 Pop_Scope;
7451 return;
7452
aa9a7dd7
AC
7453 -- A special case, N_Raise_xxx_Error can act either as a statement
7454 -- or a subexpression. We tell the difference by looking at the
7455 -- Etype. It is set to Standard_Void_Type in the statement case.
70482933 7456
d8f43ee6
HK
7457 when N_Raise_xxx_Error =>
7458 if Etype (P) = Standard_Void_Type then
7459 if P = Wrapped_Node then
7460 Store_Before_Actions_In_Scope (Ins_Actions);
7461 else
7462 Insert_List_Before_And_Analyze (P, Ins_Actions);
7463 end if;
70482933 7464
d8f43ee6 7465 return;
70482933 7466
d8f43ee6 7467 -- In the subexpression case, keep climbing
70482933 7468
d8f43ee6
HK
7469 else
7470 null;
7471 end if;
70482933
RK
7472
7473 -- If a component association appears within a loop created for
7474 -- an array aggregate, attach the actions to the association so
7475 -- they can be subsequently inserted within the loop. For other
fbf5a39b
AC
7476 -- component associations insert outside of the aggregate. For
7477 -- an association that will generate a loop, its Loop_Actions
7478 -- attribute is already initialized (see exp_aggr.adb).
70482933 7479
d4bf622f 7480 -- The list of Loop_Actions can in turn generate additional ones,
70482933
RK
7481 -- that are inserted before the associated node. If the associated
7482 -- node is outside the aggregate, the new actions are collected
d4bf622f 7483 -- at the end of the Loop_Actions, to respect the order in which
70482933
RK
7484 -- they are to be elaborated.
7485
a702c9b9
ES
7486 when N_Component_Association
7487 | N_Iterated_Component_Association
8092c199 7488 | N_Iterated_Element_Association
a702c9b9
ES
7489 =>
7490 if Nkind (Parent (P)) = N_Aggregate
7491 and then Present (Loop_Actions (P))
7492 then
7493 if Is_Empty_List (Loop_Actions (P)) then
7494 Set_Loop_Actions (P, Ins_Actions);
7495 Analyze_List (Ins_Actions);
70482933 7496 else
a702c9b9
ES
7497 declare
7498 Decl : Node_Id;
7499
7500 begin
7501 -- Check whether these actions were generated by a
d4bf622f 7502 -- declaration that is part of the Loop_Actions for
a702c9b9
ES
7503 -- the component_association.
7504
7505 Decl := Assoc_Node;
7506 while Present (Decl) loop
7507 exit when Parent (Decl) = P
7508 and then Is_List_Member (Decl)
7509 and then
7510 List_Containing (Decl) = Loop_Actions (P);
7511 Decl := Parent (Decl);
7512 end loop;
7513
7514 if Present (Decl) then
7515 Insert_List_Before_And_Analyze
7516 (Decl, Ins_Actions);
7517 else
7518 Insert_List_After_And_Analyze
7519 (Last (Loop_Actions (P)), Ins_Actions);
7520 end if;
7521 end;
70482933
RK
7522 end if;
7523
a702c9b9
ES
7524 return;
7525
7526 else
7527 null;
7528 end if;
7529
90e491a7 7530 -- Special case: an attribute denoting a procedure call
70482933 7531
d8f43ee6
HK
7532 when N_Attribute_Reference =>
7533 if Is_Procedure_Attribute_Name (Attribute_Name (P)) then
7534 if P = Wrapped_Node then
7535 Store_Before_Actions_In_Scope (Ins_Actions);
7536 else
7537 Insert_List_Before_And_Analyze (P, Ins_Actions);
7538 end if;
70482933 7539
d8f43ee6 7540 return;
70482933 7541
d8f43ee6 7542 -- In the subexpression case, keep climbing
70482933 7543
d8f43ee6
HK
7544 else
7545 null;
7546 end if;
70482933 7547
daf82dd8 7548 -- Special case: a marker
90e491a7 7549
daf82dd8
HK
7550 when N_Call_Marker
7551 | N_Variable_Reference_Marker
7552 =>
90e491a7
PMR
7553 if Is_List_Member (P) then
7554 Insert_List_Before_And_Analyze (P, Ins_Actions);
7555 return;
7556 end if;
7557
dac3bede
YM
7558 -- A contract node should not belong to the tree
7559
7560 when N_Contract =>
7561 raise Program_Error;
7562
70482933
RK
7563 -- For all other node types, keep climbing tree
7564
d8f43ee6
HK
7565 when N_Abortable_Part
7566 | N_Accept_Alternative
7567 | N_Access_Definition
7568 | N_Access_Function_Definition
7569 | N_Access_Procedure_Definition
7570 | N_Access_To_Object_Definition
7571 | N_Aggregate
7572 | N_Allocator
7573 | N_Aspect_Specification
7574 | N_Case_Expression
7575 | N_Case_Statement_Alternative
7576 | N_Character_Literal
7577 | N_Compilation_Unit
7578 | N_Compilation_Unit_Aux
7579 | N_Component_Clause
7580 | N_Component_Declaration
7581 | N_Component_Definition
7582 | N_Component_List
7583 | N_Constrained_Array_Definition
7584 | N_Decimal_Fixed_Point_Definition
7585 | N_Defining_Character_Literal
7586 | N_Defining_Identifier
7587 | N_Defining_Operator_Symbol
7588 | N_Defining_Program_Unit_Name
7589 | N_Delay_Alternative
9eb8d5b4 7590 | N_Delta_Aggregate
d8f43ee6
HK
7591 | N_Delta_Constraint
7592 | N_Derived_Type_Definition
7593 | N_Designator
7594 | N_Digits_Constraint
7595 | N_Discriminant_Association
7596 | N_Discriminant_Specification
7597 | N_Empty
7598 | N_Entry_Body_Formal_Part
7599 | N_Entry_Call_Alternative
7600 | N_Entry_Declaration
7601 | N_Entry_Index_Specification
7602 | N_Enumeration_Type_Definition
7603 | N_Error
7604 | N_Exception_Handler
7605 | N_Expanded_Name
7606 | N_Explicit_Dereference
7607 | N_Extension_Aggregate
7608 | N_Floating_Point_Definition
7609 | N_Formal_Decimal_Fixed_Point_Definition
7610 | N_Formal_Derived_Type_Definition
7611 | N_Formal_Discrete_Type_Definition
7612 | N_Formal_Floating_Point_Definition
7613 | N_Formal_Modular_Type_Definition
7614 | N_Formal_Ordinary_Fixed_Point_Definition
7615 | N_Formal_Package_Declaration
7616 | N_Formal_Private_Type_Definition
7617 | N_Formal_Incomplete_Type_Definition
7618 | N_Formal_Signed_Integer_Type_Definition
7619 | N_Function_Call
7620 | N_Function_Specification
7621 | N_Generic_Association
7622 | N_Handled_Sequence_Of_Statements
7623 | N_Identifier
7624 | N_In
7625 | N_Index_Or_Discriminant_Constraint
7626 | N_Indexed_Component
7627 | N_Integer_Literal
7628 | N_Iterator_Specification
7629 | N_Itype_Reference
7630 | N_Label
7631 | N_Loop_Parameter_Specification
7632 | N_Mod_Clause
7633 | N_Modular_Type_Definition
7634 | N_Not_In
7635 | N_Null
7636 | N_Op_Abs
7637 | N_Op_Add
7638 | N_Op_And
7639 | N_Op_Concat
7640 | N_Op_Divide
7641 | N_Op_Eq
7642 | N_Op_Expon
7643 | N_Op_Ge
7644 | N_Op_Gt
7645 | N_Op_Le
7646 | N_Op_Lt
7647 | N_Op_Minus
7648 | N_Op_Mod
7649 | N_Op_Multiply
7650 | N_Op_Ne
7651 | N_Op_Not
7652 | N_Op_Or
7653 | N_Op_Plus
7654 | N_Op_Rem
7655 | N_Op_Rotate_Left
7656 | N_Op_Rotate_Right
7657 | N_Op_Shift_Left
7658 | N_Op_Shift_Right
7659 | N_Op_Shift_Right_Arithmetic
7660 | N_Op_Subtract
7661 | N_Op_Xor
7662 | N_Operator_Symbol
7663 | N_Ordinary_Fixed_Point_Definition
7664 | N_Others_Choice
7665 | N_Package_Specification
7666 | N_Parameter_Association
7667 | N_Parameter_Specification
7668 | N_Pop_Constraint_Error_Label
7669 | N_Pop_Program_Error_Label
7670 | N_Pop_Storage_Error_Label
7671 | N_Pragma_Argument_Association
7672 | N_Procedure_Specification
7673 | N_Protected_Definition
7674 | N_Push_Constraint_Error_Label
7675 | N_Push_Program_Error_Label
7676 | N_Push_Storage_Error_Label
7677 | N_Qualified_Expression
7678 | N_Quantified_Expression
7679 | N_Raise_Expression
7680 | N_Range
7681 | N_Range_Constraint
7682 | N_Real_Literal
7683 | N_Real_Range_Specification
7684 | N_Record_Definition
7685 | N_Reference
7686 | N_SCIL_Dispatch_Table_Tag_Init
7687 | N_SCIL_Dispatching_Call
7688 | N_SCIL_Membership_Test
7689 | N_Selected_Component
7690 | N_Signed_Integer_Type_Definition
7691 | N_Single_Protected_Declaration
7692 | N_Slice
7693 | N_String_Literal
7694 | N_Subtype_Indication
7695 | N_Subunit
ae33543c 7696 | N_Target_Name
d8f43ee6
HK
7697 | N_Task_Definition
7698 | N_Terminate_Alternative
7699 | N_Triggering_Alternative
7700 | N_Type_Conversion
7701 | N_Unchecked_Expression
7702 | N_Unchecked_Type_Conversion
7703 | N_Unconstrained_Array_Definition
7704 | N_Unused_At_End
7705 | N_Unused_At_Start
7706 | N_Variant
7707 | N_Variant_Part
7708 | N_Validate_Unchecked_Conversion
7709 | N_With_Clause
70482933
RK
7710 =>
7711 null;
70482933
RK
7712 end case;
7713
70482933
RK
7714 -- If we fall through above tests, keep climbing tree
7715
7716 N := P;
7717
7718 if Nkind (Parent (N)) = N_Subunit then
7719
aa9a7dd7
AC
7720 -- This is the proper body corresponding to a stub. Insertion must
7721 -- be done at the point of the stub, which is in the declarative
7722 -- part of the parent unit.
70482933
RK
7723
7724 P := Corresponding_Stub (Parent (N));
7725
7726 else
7727 P := Parent (N);
7728 end if;
7729 end loop;
70482933
RK
7730 end Insert_Actions;
7731
7732 -- Version with check(s) suppressed
7733
7734 procedure Insert_Actions
e2819941
HK
7735 (Assoc_Node : Node_Id;
7736 Ins_Actions : List_Id;
7737 Suppress : Check_Id;
7738 Spec_Expr_OK : Boolean := False)
70482933
RK
7739 is
7740 begin
7741 if Suppress = All_Checks then
7742 declare
a7f1b24f 7743 Sva : constant Suppress_Array := Scope_Suppress.Suppress;
70482933 7744 begin
a7f1b24f 7745 Scope_Suppress.Suppress := (others => True);
e2819941 7746 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
a7f1b24f 7747 Scope_Suppress.Suppress := Sva;
70482933
RK
7748 end;
7749
7750 else
7751 declare
3217f71e 7752 Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
70482933 7753 begin
3217f71e 7754 Scope_Suppress.Suppress (Suppress) := True;
e2819941 7755 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK);
3217f71e 7756 Scope_Suppress.Suppress (Suppress) := Svg;
70482933
RK
7757 end;
7758 end if;
7759 end Insert_Actions;
7760
7761 --------------------------
7762 -- Insert_Actions_After --
7763 --------------------------
7764
7765 procedure Insert_Actions_After
7766 (Assoc_Node : Node_Id;
7767 Ins_Actions : List_Id)
7768 is
7769 begin
0e564ab4 7770 if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then
70482933
RK
7771 Store_After_Actions_In_Scope (Ins_Actions);
7772 else
7773 Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions);
7774 end if;
7775 end Insert_Actions_After;
7776
e03f7ccf
AC
7777 ------------------------
7778 -- Insert_Declaration --
7779 ------------------------
7780
7781 procedure Insert_Declaration (N : Node_Id; Decl : Node_Id) is
7782 P : Node_Id;
7783
7784 begin
7785 pragma Assert (Nkind (N) in N_Subexpr);
7786
7787 -- Climb until we find a procedure or a package
7788
adb252d8 7789 P := N;
e03f7ccf 7790 loop
adb252d8
AC
7791 pragma Assert (Present (Parent (P)));
7792 P := Parent (P);
7793
e03f7ccf 7794 if Is_List_Member (P) then
4a08c95c
AC
7795 exit when Nkind (Parent (P)) in
7796 N_Package_Specification | N_Subprogram_Body;
e03f7ccf
AC
7797
7798 -- Special handling for handled sequence of statements, we must
7799 -- insert in the statements not the exception handlers!
7800
7801 if Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements then
7802 P := First (Statements (Parent (P)));
7803 exit;
7804 end if;
7805 end if;
e03f7ccf
AC
7806 end loop;
7807
7808 -- Now do the insertion
7809
7810 Insert_Before (P, Decl);
7811 Analyze (Decl);
7812 end Insert_Declaration;
7813
70482933
RK
7814 ---------------------------------
7815 -- Insert_Library_Level_Action --
7816 ---------------------------------
7817
7818 procedure Insert_Library_Level_Action (N : Node_Id) is
7819 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
7820
7821 begin
d6fd1f07
AC
7822 Push_Scope (Cunit_Entity (Current_Sem_Unit));
7823 -- And not Main_Unit as previously. If the main unit is a body,
7824 -- the scope needed to analyze the actions is the entity of the
7825 -- corresponding declaration.
70482933
RK
7826
7827 if No (Actions (Aux)) then
7828 Set_Actions (Aux, New_List (N));
7829 else
7830 Append (N, Actions (Aux));
7831 end if;
7832
7833 Analyze (N);
7834 Pop_Scope;
7835 end Insert_Library_Level_Action;
7836
7837 ----------------------------------
7838 -- Insert_Library_Level_Actions --
7839 ----------------------------------
7840
7841 procedure Insert_Library_Level_Actions (L : List_Id) is
7842 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit));
7843
7844 begin
7845 if Is_Non_Empty_List (L) then
0712790c
ES
7846 Push_Scope (Cunit_Entity (Main_Unit));
7847 -- ??? should this be Current_Sem_Unit instead of Main_Unit?
70482933
RK
7848
7849 if No (Actions (Aux)) then
7850 Set_Actions (Aux, L);
7851 Analyze_List (L);
7852 else
7853 Insert_List_After_And_Analyze (Last (Actions (Aux)), L);
7854 end if;
7855
7856 Pop_Scope;
7857 end if;
7858 end Insert_Library_Level_Actions;
7859
7860 ----------------------
7861 -- Inside_Init_Proc --
7862 ----------------------
7863
7864 function Inside_Init_Proc return Boolean is
341e0bb6 7865 Proc : constant Entity_Id := Enclosing_Init_Proc;
70482933
RK
7866
7867 begin
341e0bb6 7868 return Proc /= Empty;
70482933
RK
7869 end Inside_Init_Proc;
7870
c7c7dd3a
EB
7871 ----------------------
7872 -- Integer_Type_For --
7873 ----------------------
7874
7875 function Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id is
7876 begin
7877 pragma Assert (S <= System_Max_Integer_Size);
7878
7879 -- This is the canonical 32-bit type
7880
7881 if S <= Standard_Integer_Size then
7882 if Uns then
7883 return Standard_Unsigned;
7884 else
7885 return Standard_Integer;
7886 end if;
7887
7888 -- This is the canonical 64-bit type
7889
7890 elsif S <= Standard_Long_Long_Integer_Size then
7891 if Uns then
7892 return Standard_Long_Long_Unsigned;
7893 else
7894 return Standard_Long_Long_Integer;
7895 end if;
7896
a5476382
EB
7897 -- This is the canonical 128-bit type
7898
7899 elsif S <= Standard_Long_Long_Long_Integer_Size then
7900 if Uns then
7901 return Standard_Long_Long_Long_Unsigned;
7902 else
7903 return Standard_Long_Long_Long_Integer;
7904 end if;
7905
c7c7dd3a
EB
7906 else
7907 raise Program_Error;
7908 end if;
7909 end Integer_Type_For;
7910
a429e6b3
AC
7911 --------------------------------------------------
7912 -- Is_Displacement_Of_Object_Or_Function_Result --
7913 --------------------------------------------------
aab08130 7914
a429e6b3 7915 function Is_Displacement_Of_Object_Or_Function_Result
aab08130
AC
7916 (Obj_Id : Entity_Id) return Boolean
7917 is
a429e6b3 7918 function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
5efb89d0
AC
7919 -- Determine whether node N denotes a controlled function call
7920
7921 function Is_Controlled_Indexing (N : Node_Id) return Boolean;
7922 -- Determine whether node N denotes a generalized indexing form which
7923 -- involves a controlled result.
aab08130
AC
7924
7925 function Is_Displace_Call (N : Node_Id) return Boolean;
5efb89d0 7926 -- Determine whether node N denotes a call to Ada.Tags.Displace
aab08130 7927
a429e6b3
AC
7928 function Is_Source_Object (N : Node_Id) return Boolean;
7929 -- Determine whether a particular node denotes a source object
7930
5efb89d0
AC
7931 function Strip (N : Node_Id) return Node_Id;
7932 -- Examine arbitrary node N by stripping various indirections and return
7933 -- the "real" node.
7934
a429e6b3
AC
7935 ---------------------------------
7936 -- Is_Controlled_Function_Call --
7937 ---------------------------------
aab08130 7938
a429e6b3 7939 function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
5efb89d0 7940 Expr : Node_Id;
f307415a 7941
aab08130 7942 begin
36295779 7943 -- When a function call appears in Object.Operation format, the
34557478
HK
7944 -- original representation has several possible forms depending on
7945 -- the availability and form of actual parameters:
bb012790 7946
a8a42b93
AC
7947 -- Obj.Func N_Selected_Component
7948 -- Obj.Func (Actual) N_Indexed_Component
7949 -- Obj.Func (Formal => Actual) N_Function_Call, whose Name is an
7950 -- N_Selected_Component
36295779 7951
5efb89d0 7952 Expr := Original_Node (N);
442d1abb
AC
7953 loop
7954 if Nkind (Expr) = N_Function_Call then
a8a42b93
AC
7955 Expr := Name (Expr);
7956
a8a42b93
AC
7957 -- "Obj.Func (Actual)" case
7958
442d1abb 7959 elsif Nkind (Expr) = N_Indexed_Component then
36295779 7960 Expr := Prefix (Expr);
f307415a 7961
442d1abb 7962 -- "Obj.Func" or "Obj.Func (Formal => Actual) case
a8a42b93 7963
442d1abb 7964 elsif Nkind (Expr) = N_Selected_Component then
36295779 7965 Expr := Selector_Name (Expr);
a8a42b93 7966
442d1abb
AC
7967 else
7968 exit;
7969 end if;
7970 end loop;
f307415a 7971
aab08130 7972 return
442d1abb
AC
7973 Nkind (Expr) in N_Has_Entity
7974 and then Present (Entity (Expr))
f307415a
AC
7975 and then Ekind (Entity (Expr)) = E_Function
7976 and then Needs_Finalization (Etype (Entity (Expr)));
a429e6b3 7977 end Is_Controlled_Function_Call;
aab08130 7978
5efb89d0
AC
7979 ----------------------------
7980 -- Is_Controlled_Indexing --
7981 ----------------------------
7982
7983 function Is_Controlled_Indexing (N : Node_Id) return Boolean is
7984 Expr : constant Node_Id := Original_Node (N);
7985
7986 begin
7987 return
7988 Nkind (Expr) = N_Indexed_Component
7989 and then Present (Generalized_Indexing (Expr))
7990 and then Needs_Finalization (Etype (Expr));
7991 end Is_Controlled_Indexing;
7992
aab08130
AC
7993 ----------------------
7994 -- Is_Displace_Call --
7995 ----------------------
7996
7997 function Is_Displace_Call (N : Node_Id) return Boolean is
5efb89d0 7998 Call : constant Node_Id := Strip (N);
aab08130
AC
7999
8000 begin
aab08130 8001 return
a429e6b3
AC
8002 Present (Call)
8003 and then Nkind (Call) = N_Function_Call
315f0c42 8004 and then Nkind (Name (Call)) in N_Has_Entity
aab08130
AC
8005 and then Is_RTE (Entity (Name (Call)), RE_Displace);
8006 end Is_Displace_Call;
8007
a429e6b3
AC
8008 ----------------------
8009 -- Is_Source_Object --
8010 ----------------------
8011
8012 function Is_Source_Object (N : Node_Id) return Boolean is
5efb89d0 8013 Obj : constant Node_Id := Strip (N);
c23c86bb 8014
a429e6b3 8015 begin
5efb89d0
AC
8016 return
8017 Present (Obj)
8018 and then Comes_From_Source (Obj)
8019 and then Nkind (Obj) in N_Has_Entity
8020 and then Is_Object (Entity (Obj));
8021 end Is_Source_Object;
8022
8023 -----------
8024 -- Strip --
8025 -----------
c23c86bb 8026
5efb89d0
AC
8027 function Strip (N : Node_Id) return Node_Id is
8028 Result : Node_Id;
8029
8030 begin
8031 Result := N;
c23c86bb 8032 loop
5efb89d0
AC
8033 if Nkind (Result) = N_Explicit_Dereference then
8034 Result := Prefix (Result);
c23c86bb 8035
4a08c95c
AC
8036 elsif Nkind (Result) in
8037 N_Type_Conversion | N_Unchecked_Type_Conversion
c23c86bb 8038 then
5efb89d0 8039 Result := Expression (Result);
c23c86bb
AC
8040
8041 else
8042 exit;
8043 end if;
8044 end loop;
8045
5efb89d0
AC
8046 return Result;
8047 end Strip;
a429e6b3 8048
aab08130
AC
8049 -- Local variables
8050
5efb89d0 8051 Obj_Decl : constant Node_Id := Declaration_Node (Obj_Id);
aab08130 8052 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
5efb89d0
AC
8053 Orig_Decl : constant Node_Id := Original_Node (Obj_Decl);
8054 Orig_Expr : Node_Id;
aab08130 8055
a429e6b3 8056 -- Start of processing for Is_Displacement_Of_Object_Or_Function_Result
aab08130
AC
8057
8058 begin
a429e6b3 8059 -- Case 1:
aab08130 8060
a429e6b3 8061 -- Obj : CW_Type := Function_Call (...);
aab08130 8062
5efb89d0 8063 -- is rewritten into:
aab08130 8064
5efb89d0
AC
8065 -- Temp : ... := Function_Call (...)'reference;
8066 -- Obj : CW_Type renames (... Ada.Tags.Displace (Temp));
aab08130 8067
a429e6b3
AC
8068 -- where the return type of the function and the class-wide type require
8069 -- dispatch table pointer displacement.
8070
8071 -- Case 2:
8072
5efb89d0
AC
8073 -- Obj : CW_Type := Container (...);
8074
8075 -- is rewritten into:
8076
8077 -- Temp : ... := Function_Call (Container, ...)'reference;
8078 -- Obj : CW_Type renames (... Ada.Tags.Displace (Temp));
8079
8080 -- where the container element type and the class-wide type require
8081 -- dispatch table pointer dispacement.
8082
8083 -- Case 3:
8084
a429e6b3
AC
8085 -- Obj : CW_Type := Src_Obj;
8086
5efb89d0 8087 -- is rewritten into:
a429e6b3
AC
8088
8089 -- Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
8090
8091 -- where the type of the source object and the class-wide type require
aab08130
AC
8092 -- dispatch table pointer displacement.
8093
5efb89d0
AC
8094 if Nkind (Obj_Decl) = N_Object_Renaming_Declaration
8095 and then Is_Class_Wide_Type (Obj_Typ)
8096 and then Is_Displace_Call (Renamed_Object (Obj_Id))
8097 and then Nkind (Orig_Decl) = N_Object_Declaration
8098 and then Comes_From_Source (Orig_Decl)
8099 then
8100 Orig_Expr := Expression (Orig_Decl);
8101
8102 return
8103 Is_Controlled_Function_Call (Orig_Expr)
8104 or else Is_Controlled_Indexing (Orig_Expr)
8105 or else Is_Source_Object (Orig_Expr);
8106 end if;
8107
8108 return False;
a429e6b3 8109 end Is_Displacement_Of_Object_Or_Function_Result;
aab08130 8110
df3e68b1
HK
8111 ------------------------------
8112 -- Is_Finalizable_Transient --
8113 ------------------------------
8114
8115 function Is_Finalizable_Transient
8116 (Decl : Node_Id;
8117 Rel_Node : Node_Id) return Boolean
8118 is
f7bb41af
AC
8119 Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
8120 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
df3e68b1
HK
8121
8122 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean;
8123 -- Determine whether transient object Trans_Id is initialized either
8124 -- by a function call which returns an access type or simply renames
8125 -- another pointer.
8126
8127 function Initialized_By_Aliased_BIP_Func_Call
8128 (Trans_Id : Entity_Id) return Boolean;
8129 -- Determine whether transient object Trans_Id is initialized by a
8130 -- build-in-place function call where the BIPalloc parameter is of
8131 -- value 1 and BIPaccess is not null. This case creates an aliasing
8132 -- between the returned value and the value denoted by BIPaccess.
8133
f7bb41af 8134 function Is_Aliased
df3e68b1
HK
8135 (Trans_Id : Entity_Id;
8136 First_Stmt : Node_Id) return Boolean;
f7bb41af
AC
8137 -- Determine whether transient object Trans_Id has been renamed or
8138 -- aliased through 'reference in the statement list starting from
8139 -- First_Stmt.
8140
8141 function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
8142 -- Determine whether transient object Trans_Id is allocated on the heap
df3e68b1 8143
2f7b7467
AC
8144 function Is_Iterated_Container
8145 (Trans_Id : Entity_Id;
8146 First_Stmt : Node_Id) return Boolean;
8147 -- Determine whether transient object Trans_Id denotes a container which
8148 -- is in the process of being iterated in the statement list starting
8149 -- from First_Stmt.
8150
13209acd
AC
8151 function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean;
8152 -- Return True if N is directly part of a build-in-place return
8153 -- statement.
8154
df3e68b1
HK
8155 ---------------------------
8156 -- Initialized_By_Access --
8157 ---------------------------
8158
8159 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is
8160 Expr : constant Node_Id := Expression (Parent (Trans_Id));
8161
8162 begin
8163 return
8164 Present (Expr)
8165 and then Nkind (Expr) /= N_Reference
8166 and then Is_Access_Type (Etype (Expr));
8167 end Initialized_By_Access;
8168
8169 ------------------------------------------
8170 -- Initialized_By_Aliased_BIP_Func_Call --
8171 ------------------------------------------
8172
8173 function Initialized_By_Aliased_BIP_Func_Call
8174 (Trans_Id : Entity_Id) return Boolean
8175 is
8176 Call : Node_Id := Expression (Parent (Trans_Id));
8177
8178 begin
8179 -- Build-in-place calls usually appear in 'reference format
8180
8181 if Nkind (Call) = N_Reference then
8182 Call := Prefix (Call);
8183 end if;
8184
d4dfb005
BD
8185 Call := Unqual_Conv (Call);
8186
df3e68b1
HK
8187 if Is_Build_In_Place_Function_Call (Call) then
8188 declare
8189 Access_Nam : Name_Id := No_Name;
8190 Access_OK : Boolean := False;
8191 Actual : Node_Id;
8192 Alloc_Nam : Name_Id := No_Name;
8193 Alloc_OK : Boolean := False;
8194 Formal : Node_Id;
8195 Func_Id : Entity_Id;
8196 Param : Node_Id;
8197
8198 begin
8199 -- Examine all parameter associations of the function call
8200
8201 Param := First (Parameter_Associations (Call));
8202 while Present (Param) loop
8203 if Nkind (Param) = N_Parameter_Association
8204 and then Nkind (Selector_Name (Param)) = N_Identifier
8205 then
8206 Actual := Explicit_Actual_Parameter (Param);
8207 Formal := Selector_Name (Param);
8208
8209 -- Construct the names of formals BIPaccess and BIPalloc
8210 -- using the function name retrieved from an arbitrary
8211 -- formal.
8212
8213 if Access_Nam = No_Name
8214 and then Alloc_Nam = No_Name
8215 and then Present (Entity (Formal))
8216 then
8217 Func_Id := Scope (Entity (Formal));
8218
8219 Access_Nam :=
8220 New_External_Name (Chars (Func_Id),
8221 BIP_Formal_Suffix (BIP_Object_Access));
8222
8223 Alloc_Nam :=
8224 New_External_Name (Chars (Func_Id),
8225 BIP_Formal_Suffix (BIP_Alloc_Form));
8226 end if;
8227
8228 -- A match for BIPaccess => Temp has been found
8229
8230 if Chars (Formal) = Access_Nam
8231 and then Nkind (Actual) /= N_Null
8232 then
8233 Access_OK := True;
8234 end if;
8235
8236 -- A match for BIPalloc => 1 has been found
8237
8238 if Chars (Formal) = Alloc_Nam
8239 and then Nkind (Actual) = N_Integer_Literal
8240 and then Intval (Actual) = Uint_1
8241 then
8242 Alloc_OK := True;
8243 end if;
8244 end if;
8245
8246 Next (Param);
8247 end loop;
8248
0e564ab4 8249 return Access_OK and Alloc_OK;
df3e68b1
HK
8250 end;
8251 end if;
8252
8253 return False;
8254 end Initialized_By_Aliased_BIP_Func_Call;
8255
df3e68b1 8256 ----------------
f7bb41af 8257 -- Is_Aliased --
df3e68b1
HK
8258 ----------------
8259
f7bb41af 8260 function Is_Aliased
df3e68b1
HK
8261 (Trans_Id : Entity_Id;
8262 First_Stmt : Node_Id) return Boolean
8263 is
c5f5123f 8264 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id;
df3e68b1
HK
8265 -- Given an object renaming declaration, retrieve the entity of the
8266 -- renamed name. Return Empty if the renamed name is anything other
8267 -- than a variable or a constant.
8268
c5f5123f
AC
8269 -------------------------
8270 -- Find_Renamed_Object --
8271 -------------------------
df3e68b1 8272
c5f5123f
AC
8273 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is
8274 Ren_Obj : Node_Id := Empty;
df3e68b1 8275
c5f5123f
AC
8276 function Find_Object (N : Node_Id) return Traverse_Result;
8277 -- Try to detect an object which is either a constant or a
8278 -- variable.
0180fd26 8279
c5f5123f
AC
8280 -----------------
8281 -- Find_Object --
8282 -----------------
8283
8284 function Find_Object (N : Node_Id) return Traverse_Result is
8285 begin
8286 -- Stop the search once a constant or a variable has been
8287 -- detected.
8288
8289 if Nkind (N) = N_Identifier
8290 and then Present (Entity (N))
4a08c95c 8291 and then Ekind (Entity (N)) in E_Constant | E_Variable
0180fd26 8292 then
c5f5123f
AC
8293 Ren_Obj := Entity (N);
8294 return Abandon;
df3e68b1 8295 end if;
df3e68b1 8296
c5f5123f
AC
8297 return OK;
8298 end Find_Object;
8299
8300 procedure Search is new Traverse_Proc (Find_Object);
8301
8302 -- Local variables
8303
8304 Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl));
8305
8306 -- Start of processing for Find_Renamed_Object
8307
8308 begin
8309 -- Actions related to dispatching calls may appear as renamings of
8310 -- tags. Do not process this type of renaming because it does not
8311 -- use the actual value of the object.
8312
8313 if not Is_RTE (Typ, RE_Tag_Ptr) then
8314 Search (Name (Ren_Decl));
df3e68b1
HK
8315 end if;
8316
c5f5123f
AC
8317 return Ren_Obj;
8318 end Find_Renamed_Object;
df3e68b1 8319
f7bb41af 8320 -- Local variables
df3e68b1 8321
f7bb41af
AC
8322 Expr : Node_Id;
8323 Ren_Obj : Entity_Id;
8324 Stmt : Node_Id;
df3e68b1 8325
f7bb41af 8326 -- Start of processing for Is_Aliased
df3e68b1 8327
f7bb41af 8328 begin
4b17187f
AC
8329 -- A controlled transient object is not considered aliased when it
8330 -- appears inside an expression_with_actions node even when there are
8331 -- explicit aliases of it:
8332
8333 -- do
937e9676 8334 -- Trans_Id : Ctrl_Typ ...; -- transient object
4b17187f
AC
8335 -- Alias : ... := Trans_Id; -- object is aliased
8336 -- Val : constant Boolean :=
8337 -- ... Alias ...; -- aliasing ends
8338 -- <finalize Trans_Id> -- object safe to finalize
8339 -- in Val end;
8340
8341 -- Expansion ensures that all aliases are encapsulated in the actions
8342 -- list and do not leak to the expression by forcing the evaluation
8343 -- of the expression.
8344
8345 if Nkind (Rel_Node) = N_Expression_With_Actions then
8346 return False;
f7bb41af 8347
4b17187f
AC
8348 -- Otherwise examine the statements after the controlled transient
8349 -- object and look for various forms of aliasing.
df3e68b1 8350
4b17187f
AC
8351 else
8352 Stmt := First_Stmt;
8353 while Present (Stmt) loop
8354 if Nkind (Stmt) = N_Object_Declaration then
8355 Expr := Expression (Stmt);
8356
8357 -- Aliasing of the form:
8358 -- Obj : ... := Trans_Id'reference;
8359
8360 if Present (Expr)
8361 and then Nkind (Expr) = N_Reference
8362 and then Nkind (Prefix (Expr)) = N_Identifier
8363 and then Entity (Prefix (Expr)) = Trans_Id
8364 then
8365 return True;
8366 end if;
8367
8368 elsif Nkind (Stmt) = N_Object_Renaming_Declaration then
8369 Ren_Obj := Find_Renamed_Object (Stmt);
8370
8371 -- Aliasing of the form:
8372 -- Obj : ... renames ... Trans_Id ...;
8373
8374 if Present (Ren_Obj) and then Ren_Obj = Trans_Id then
8375 return True;
8376 end if;
df3e68b1 8377 end if;
df3e68b1 8378
4b17187f
AC
8379 Next (Stmt);
8380 end loop;
df3e68b1 8381
4b17187f
AC
8382 return False;
8383 end if;
f7bb41af
AC
8384 end Is_Aliased;
8385
8386 ------------------
8387 -- Is_Allocated --
8388 ------------------
8389
8390 function Is_Allocated (Trans_Id : Entity_Id) return Boolean is
8391 Expr : constant Node_Id := Expression (Parent (Trans_Id));
f7bb41af
AC
8392 begin
8393 return
8394 Is_Access_Type (Etype (Trans_Id))
8395 and then Present (Expr)
8396 and then Nkind (Expr) = N_Allocator;
8397 end Is_Allocated;
df3e68b1 8398
2f7b7467
AC
8399 ---------------------------
8400 -- Is_Iterated_Container --
8401 ---------------------------
8402
8403 function Is_Iterated_Container
8404 (Trans_Id : Entity_Id;
8405 First_Stmt : Node_Id) return Boolean
8406 is
8407 Aspect : Node_Id;
8408 Call : Node_Id;
8409 Iter : Entity_Id;
8410 Param : Node_Id;
8411 Stmt : Node_Id;
8412 Typ : Entity_Id;
8413
8414 begin
8415 -- It is not possible to iterate over containers in non-Ada 2012 code
8416
8417 if Ada_Version < Ada_2012 then
8418 return False;
8419 end if;
8420
8421 Typ := Etype (Trans_Id);
8422
8423 -- Handle access type created for secondary stack use
8424
8425 if Is_Access_Type (Typ) then
8426 Typ := Designated_Type (Typ);
8427 end if;
8428
46de64ca
AC
8429 -- Look for aspect Default_Iterator. It may be part of a type
8430 -- declaration for a container, or inherited from a base type
8431 -- or parent type.
2f7b7467 8432
46de64ca 8433 Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator);
2f7b7467 8434
46de64ca
AC
8435 if Present (Aspect) then
8436 Iter := Entity (Aspect);
2f7b7467 8437
46de64ca
AC
8438 -- Examine the statements following the container object and
8439 -- look for a call to the default iterate routine where the
8440 -- first parameter is the transient. Such a call appears as:
2f7b7467 8441
46de64ca
AC
8442 -- It : Access_To_CW_Iterator :=
8443 -- Iterate (Tran_Id.all, ...)'reference;
2f7b7467 8444
46de64ca
AC
8445 Stmt := First_Stmt;
8446 while Present (Stmt) loop
2f7b7467 8447
46de64ca
AC
8448 -- Detect an object declaration which is initialized by a
8449 -- secondary stack function call.
2f7b7467 8450
46de64ca
AC
8451 if Nkind (Stmt) = N_Object_Declaration
8452 and then Present (Expression (Stmt))
8453 and then Nkind (Expression (Stmt)) = N_Reference
c5c780e6 8454 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call
46de64ca
AC
8455 then
8456 Call := Prefix (Expression (Stmt));
2f7b7467 8457
46de64ca
AC
8458 -- The call must invoke the default iterate routine of
8459 -- the container and the transient object must appear as
8460 -- the first actual parameter. Skip any calls whose names
8461 -- are not entities.
2f7b7467 8462
46de64ca
AC
8463 if Is_Entity_Name (Name (Call))
8464 and then Entity (Name (Call)) = Iter
8465 and then Present (Parameter_Associations (Call))
8466 then
8467 Param := First (Parameter_Associations (Call));
2f7b7467 8468
46de64ca
AC
8469 if Nkind (Param) = N_Explicit_Dereference
8470 and then Entity (Prefix (Param)) = Trans_Id
8471 then
8472 return True;
2f7b7467
AC
8473 end if;
8474 end if;
46de64ca 8475 end if;
2f7b7467 8476
46de64ca
AC
8477 Next (Stmt);
8478 end loop;
2f7b7467
AC
8479 end if;
8480
8481 return False;
8482 end Is_Iterated_Container;
8483
13209acd
AC
8484 -------------------------------------
8485 -- Is_Part_Of_BIP_Return_Statement --
8486 -------------------------------------
8487
8488 function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean is
8489 Subp : constant Entity_Id := Current_Subprogram;
8490 Context : Node_Id;
8491 begin
8492 -- First check if N is part of a BIP function
8493
8494 if No (Subp)
8495 or else not Is_Build_In_Place_Function (Subp)
8496 then
8497 return False;
8498 end if;
8499
8500 -- Then check whether N is a complete part of a return statement
8501 -- Should we consider other node kinds to go up the tree???
8502
8503 Context := N;
8504 loop
8505 case Nkind (Context) is
8506 when N_Expression_With_Actions => Context := Parent (Context);
8507 when N_Simple_Return_Statement => return True;
8508 when others => return False;
8509 end case;
8510 end loop;
8511 end Is_Part_Of_BIP_Return_Statement;
8512
4b17187f
AC
8513 -- Local variables
8514
8515 Desig : Entity_Id := Obj_Typ;
8516
df3e68b1
HK
8517 -- Start of processing for Is_Finalizable_Transient
8518
8519 begin
8520 -- Handle access types
8521
8522 if Is_Access_Type (Desig) then
8523 Desig := Available_View (Designated_Type (Desig));
8524 end if;
8525
8526 return
4a08c95c 8527 Ekind (Obj_Id) in E_Constant | E_Variable
df3e68b1
HK
8528 and then Needs_Finalization (Desig)
8529 and then Requires_Transient_Scope (Desig)
8530 and then Nkind (Rel_Node) /= N_Simple_Return_Statement
13209acd 8531 and then not Is_Part_Of_BIP_Return_Statement (Rel_Node)
df3e68b1 8532
937e9676
AC
8533 -- Do not consider a transient object that was already processed
8534
8535 and then not Is_Finalized_Transient (Obj_Id)
8536
2c17ca0a
AC
8537 -- Do not consider renamed or 'reference-d transient objects because
8538 -- the act of renaming extends the object's lifetime.
f7bb41af
AC
8539
8540 and then not Is_Aliased (Obj_Id, Decl)
8541
2c17ca0a
AC
8542 -- Do not consider transient objects allocated on the heap since
8543 -- they are attached to a finalization master.
df3e68b1
HK
8544
8545 and then not Is_Allocated (Obj_Id)
8546
2c17ca0a 8547 -- If the transient object is a pointer, check that it is not
7c4d86c9 8548 -- initialized by a function that returns a pointer or acts as a
2c17ca0a 8549 -- renaming of another pointer.
df3e68b1 8550
13209acd
AC
8551 and then not
8552 (Is_Access_Type (Obj_Typ) and then Initialized_By_Access (Obj_Id))
df3e68b1 8553
2c17ca0a
AC
8554 -- Do not consider transient objects which act as indirect aliases
8555 -- of build-in-place function results.
df3e68b1 8556
2d395256
AC
8557 and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id)
8558
2c17ca0a 8559 -- Do not consider conversions of tags to class-wide types
2d395256 8560
aab08130 8561 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
2f7b7467 8562
4b17187f
AC
8563 -- Do not consider iterators because those are treated as normal
8564 -- controlled objects and are processed by the usual finalization
8565 -- machinery. This avoids the double finalization of an iterator.
8566
8567 and then not Is_Iterator (Desig)
8568
2f7b7467
AC
8569 -- Do not consider containers in the context of iterator loops. Such
8570 -- transient objects must exist for as long as the loop is around,
8571 -- otherwise any operation carried out by the iterator will fail.
8572
8573 and then not Is_Iterated_Container (Obj_Id, Decl);
df3e68b1
HK
8574 end Is_Finalizable_Transient;
8575
6fb4cdde
AC
8576 ---------------------------------
8577 -- Is_Fully_Repped_Tagged_Type --
8578 ---------------------------------
8579
8580 function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is
8581 U : constant Entity_Id := Underlying_Type (T);
8582 Comp : Entity_Id;
8583
8584 begin
8585 if No (U) or else not Is_Tagged_Type (U) then
8586 return False;
8587 elsif Has_Discriminants (U) then
8588 return False;
8589 elsif not Has_Specified_Layout (U) then
8590 return False;
8591 end if;
8592
1f159b86
BD
8593 -- Here we have a tagged type, see if it has any component (other than
8594 -- tag and parent) with no component_clause. If so, we return False.
6fb4cdde
AC
8595
8596 Comp := First_Component (U);
8597 while Present (Comp) loop
8598 if not Is_Tag (Comp)
8599 and then Chars (Comp) /= Name_uParent
8600 and then No (Component_Clause (Comp))
8601 then
8602 return False;
8603 else
8604 Next_Component (Comp);
8605 end if;
8606 end loop;
8607
1f159b86 8608 -- All components have clauses
6fb4cdde
AC
8609
8610 return True;
8611 end Is_Fully_Repped_Tagged_Type;
8612
86cde7b1
RD
8613 ----------------------------------
8614 -- Is_Library_Level_Tagged_Type --
8615 ----------------------------------
8616
8617 function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is
8618 begin
0e564ab4 8619 return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ);
86cde7b1
RD
8620 end Is_Library_Level_Tagged_Type;
8621
df3e68b1
HK
8622 --------------------------
8623 -- Is_Non_BIP_Func_Call --
8624 --------------------------
8625
8626 function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is
8627 begin
8628 -- The expected call is of the format
8629 --
8630 -- Func_Call'reference
8631
8632 return
8633 Nkind (Expr) = N_Reference
8634 and then Nkind (Prefix (Expr)) = N_Function_Call
8635 and then not Is_Build_In_Place_Function_Call (Prefix (Expr));
8636 end Is_Non_BIP_Func_Call;
8637
fbf5a39b
AC
8638 ----------------------------------
8639 -- Is_Possibly_Unaligned_Object --
8640 ----------------------------------
8641
f44fe430
RD
8642 function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is
8643 T : constant Entity_Id := Etype (N);
8644
fbf5a39b 8645 begin
f44fe430 8646 -- If renamed object, apply test to underlying object
fbf5a39b 8647
f44fe430
RD
8648 if Is_Entity_Name (N)
8649 and then Is_Object (Entity (N))
8650 and then Present (Renamed_Object (Entity (N)))
8651 then
8652 return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N)));
fbf5a39b
AC
8653 end if;
8654
273adcdf
AC
8655 -- Tagged and controlled types and aliased types are always aligned, as
8656 -- are concurrent types.
fbf5a39b 8657
f44fe430
RD
8658 if Is_Aliased (T)
8659 or else Has_Controlled_Component (T)
8660 or else Is_Concurrent_Type (T)
8661 or else Is_Tagged_Type (T)
8662 or else Is_Controlled (T)
fbf5a39b 8663 then
f44fe430 8664 return False;
fbf5a39b
AC
8665 end if;
8666
8667 -- If this is an element of a packed array, may be unaligned
8668
f44fe430 8669 if Is_Ref_To_Bit_Packed_Array (N) then
fbf5a39b
AC
8670 return True;
8671 end if;
8672
1adaea16 8673 -- Case of indexed component reference: test whether prefix is unaligned
fbf5a39b 8674
1adaea16
AC
8675 if Nkind (N) = N_Indexed_Component then
8676 return Is_Possibly_Unaligned_Object (Prefix (N));
8677
8678 -- Case of selected component reference
8679
8680 elsif Nkind (N) = N_Selected_Component then
f44fe430
RD
8681 declare
8682 P : constant Node_Id := Prefix (N);
8683 C : constant Entity_Id := Entity (Selector_Name (N));
8684 M : Nat;
8685 S : Nat;
fbf5a39b 8686
f44fe430 8687 begin
3f833dc2 8688 -- If component reference is for an array with nonstatic bounds,
273adcdf 8689 -- then it is always aligned: we can only process unaligned arrays
2c17ca0a 8690 -- with static bounds (more precisely compile time known bounds).
fbf5a39b 8691
f44fe430
RD
8692 if Is_Array_Type (T)
8693 and then not Compile_Time_Known_Bounds (T)
8694 then
8695 return False;
8696 end if;
fbf5a39b 8697
f44fe430 8698 -- If component is aliased, it is definitely properly aligned
fbf5a39b 8699
f44fe430
RD
8700 if Is_Aliased (C) then
8701 return False;
8702 end if;
8703
8704 -- If component is for a type implemented as a scalar, and the
8705 -- record is packed, and the component is other than the first
8706 -- component of the record, then the component may be unaligned.
8707
8708 if Is_Packed (Etype (P))
8adcacef
RD
8709 and then Represented_As_Scalar (Etype (C))
8710 and then First_Entity (Scope (C)) /= C
f44fe430
RD
8711 then
8712 return True;
8713 end if;
8714
8715 -- Compute maximum possible alignment for T
8716
8717 -- If alignment is known, then that settles things
8718
8719 if Known_Alignment (T) then
8720 M := UI_To_Int (Alignment (T));
8721
8722 -- If alignment is not known, tentatively set max alignment
8723
8724 else
8725 M := Ttypes.Maximum_Alignment;
8726
8727 -- We can reduce this if the Esize is known since the default
8728 -- alignment will never be more than the smallest power of 2
8729 -- that does not exceed this Esize value.
8730
8731 if Known_Esize (T) then
8732 S := UI_To_Int (Esize (T));
8733
8734 while (M / 2) >= S loop
8735 M := M / 2;
8736 end loop;
8737 end if;
8738 end if;
8739
f44fe430
RD
8740 -- Case of component clause present which may specify an
8741 -- unaligned position.
8742
8743 if Present (Component_Clause (C)) then
8744
8745 -- Otherwise we can do a test to make sure that the actual
8746 -- start position in the record, and the length, are both
8747 -- consistent with the required alignment. If not, we know
8748 -- that we are unaligned.
8749
8750 declare
8751 Align_In_Bits : constant Nat := M * System_Storage_Unit;
92a68a04
HK
8752 Comp : Entity_Id;
8753
f44fe430 8754 begin
92a68a04
HK
8755 Comp := C;
8756
294e7bbb
EB
8757 -- For a component inherited in a record extension, the
8758 -- clause is inherited but position and size are not set.
8759
8760 if Is_Base_Type (Etype (P))
8761 and then Is_Tagged_Type (Etype (P))
92a68a04 8762 and then Present (Original_Record_Component (Comp))
294e7bbb 8763 then
92a68a04 8764 Comp := Original_Record_Component (Comp);
294e7bbb
EB
8765 end if;
8766
92a68a04
HK
8767 if Component_Bit_Offset (Comp) mod Align_In_Bits /= 0
8768 or else Esize (Comp) mod Align_In_Bits /= 0
f44fe430
RD
8769 then
8770 return True;
8771 end if;
8772 end;
8773 end if;
8774
8775 -- Otherwise, for a component reference, test prefix
8776
8777 return Is_Possibly_Unaligned_Object (P);
8778 end;
fbf5a39b
AC
8779
8780 -- If not a component reference, must be aligned
8781
8782 else
8783 return False;
8784 end if;
8785 end Is_Possibly_Unaligned_Object;
8786
8787 ---------------------------------
8788 -- Is_Possibly_Unaligned_Slice --
8789 ---------------------------------
8790
f44fe430 8791 function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is
fbf5a39b 8792 begin
0712790c 8793 -- Go to renamed object
246d2ceb 8794
f44fe430
RD
8795 if Is_Entity_Name (N)
8796 and then Is_Object (Entity (N))
8797 and then Present (Renamed_Object (Entity (N)))
fbf5a39b 8798 then
f44fe430 8799 return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N)));
fbf5a39b
AC
8800 end if;
8801
246d2ceb 8802 -- The reference must be a slice
fbf5a39b 8803
f44fe430 8804 if Nkind (N) /= N_Slice then
246d2ceb 8805 return False;
fbf5a39b
AC
8806 end if;
8807
fbf5a39b
AC
8808 -- If it is a slice, then look at the array type being sliced
8809
8810 declare
f44fe430 8811 Sarr : constant Node_Id := Prefix (N);
246d2ceb
AC
8812 -- Prefix of the slice, i.e. the array being sliced
8813
f44fe430 8814 Styp : constant Entity_Id := Etype (Prefix (N));
246d2ceb
AC
8815 -- Type of the array being sliced
8816
8817 Pref : Node_Id;
8818 Ptyp : Entity_Id;
fbf5a39b
AC
8819
8820 begin
246d2ceb
AC
8821 -- The problems arise if the array object that is being sliced
8822 -- is a component of a record or array, and we cannot guarantee
8823 -- the alignment of the array within its containing object.
fbf5a39b 8824
246d2ceb
AC
8825 -- To investigate this, we look at successive prefixes to see
8826 -- if we have a worrisome indexed or selected component.
fbf5a39b 8827
246d2ceb
AC
8828 Pref := Sarr;
8829 loop
8830 -- Case of array is part of an indexed component reference
fbf5a39b 8831
246d2ceb
AC
8832 if Nkind (Pref) = N_Indexed_Component then
8833 Ptyp := Etype (Prefix (Pref));
8834
273adcdf
AC
8835 -- The only problematic case is when the array is packed, in
8836 -- which case we really know nothing about the alignment of
8837 -- individual components.
246d2ceb
AC
8838
8839 if Is_Bit_Packed_Array (Ptyp) then
8840 return True;
8841 end if;
8842
8843 -- Case of array is part of a selected component reference
8844
8845 elsif Nkind (Pref) = N_Selected_Component then
8846 Ptyp := Etype (Prefix (Pref));
8847
8848 -- We are definitely in trouble if the record in question
8849 -- has an alignment, and either we know this alignment is
273adcdf 8850 -- inconsistent with the alignment of the slice, or we don't
c3a75a09
EB
8851 -- know what the alignment of the slice should be. But this
8852 -- really matters only if the target has strict alignment.
246d2ceb 8853
c3a75a09
EB
8854 if Target_Strict_Alignment
8855 and then Known_Alignment (Ptyp)
246d2ceb 8856 and then (Unknown_Alignment (Styp)
0e564ab4 8857 or else Alignment (Styp) > Alignment (Ptyp))
246d2ceb
AC
8858 then
8859 return True;
8860 end if;
8861
8862 -- We are in potential trouble if the record type is packed.
8863 -- We could special case when we know that the array is the
8864 -- first component, but that's not such a simple case ???
8865
8866 if Is_Packed (Ptyp) then
8867 return True;
8868 end if;
8869
8870 -- We are in trouble if there is a component clause, and
8871 -- either we do not know the alignment of the slice, or
8872 -- the alignment of the slice is inconsistent with the
8873 -- bit position specified by the component clause.
8874
8875 declare
8876 Field : constant Entity_Id := Entity (Selector_Name (Pref));
8877 begin
8878 if Present (Component_Clause (Field))
8879 and then
8880 (Unknown_Alignment (Styp)
8881 or else
8882 (Component_Bit_Offset (Field) mod
8883 (System_Storage_Unit * Alignment (Styp))) /= 0)
8884 then
8885 return True;
8886 end if;
8887 end;
8888
273adcdf
AC
8889 -- For cases other than selected or indexed components we know we
8890 -- are OK, since no issues arise over alignment.
246d2ceb
AC
8891
8892 else
8893 return False;
8894 end if;
8895
8896 -- We processed an indexed component or selected component
8897 -- reference that looked safe, so keep checking prefixes.
8898
8899 Pref := Prefix (Pref);
8900 end loop;
fbf5a39b
AC
8901 end;
8902 end Is_Possibly_Unaligned_Slice;
8903
df3e68b1
HK
8904 -------------------------------
8905 -- Is_Related_To_Func_Return --
8906 -------------------------------
8907
8908 function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is
8909 Expr : constant Node_Id := Related_Expression (Id);
df3e68b1 8910 begin
56bedb14
SB
8911 -- In the case of a function with a class-wide result that returns
8912 -- a call to a function with a specific result, we introduce a
8913 -- type conversion for the return expression. We do not want that
8914 -- type conversion to influence the result of this function.
8915
df3e68b1
HK
8916 return
8917 Present (Expr)
56bedb14 8918 and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference
df3e68b1
HK
8919 and then Nkind (Parent (Expr)) = N_Simple_Return_Statement;
8920 end Is_Related_To_Func_Return;
8921
70482933
RK
8922 --------------------------------
8923 -- Is_Ref_To_Bit_Packed_Array --
8924 --------------------------------
8925
f44fe430 8926 function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is
70482933
RK
8927 Result : Boolean;
8928 Expr : Node_Id;
8929
8930 begin
f44fe430
RD
8931 if Is_Entity_Name (N)
8932 and then Is_Object (Entity (N))
8933 and then Present (Renamed_Object (Entity (N)))
fbf5a39b 8934 then
f44fe430 8935 return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N)));
fbf5a39b
AC
8936 end if;
8937
4a08c95c 8938 if Nkind (N) in N_Indexed_Component | N_Selected_Component then
f44fe430 8939 if Is_Bit_Packed_Array (Etype (Prefix (N))) then
70482933
RK
8940 Result := True;
8941 else
f44fe430 8942 Result := Is_Ref_To_Bit_Packed_Array (Prefix (N));
70482933
RK
8943 end if;
8944
f44fe430
RD
8945 if Result and then Nkind (N) = N_Indexed_Component then
8946 Expr := First (Expressions (N));
70482933
RK
8947 while Present (Expr) loop
8948 Force_Evaluation (Expr);
8949 Next (Expr);
8950 end loop;
8951 end if;
8952
8953 return Result;
8954
8955 else
8956 return False;
8957 end if;
8958 end Is_Ref_To_Bit_Packed_Array;
8959
8960 --------------------------------
fbf5a39b 8961 -- Is_Ref_To_Bit_Packed_Slice --
70482933
RK
8962 --------------------------------
8963
f44fe430 8964 function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is
70482933 8965 begin
ea985d95
RD
8966 if Nkind (N) = N_Type_Conversion then
8967 return Is_Ref_To_Bit_Packed_Slice (Expression (N));
8968
8969 elsif Is_Entity_Name (N)
f44fe430
RD
8970 and then Is_Object (Entity (N))
8971 and then Present (Renamed_Object (Entity (N)))
fbf5a39b 8972 then
f44fe430 8973 return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N)));
fbf5a39b 8974
ea985d95 8975 elsif Nkind (N) = N_Slice
f44fe430 8976 and then Is_Bit_Packed_Array (Etype (Prefix (N)))
70482933
RK
8977 then
8978 return True;
8979
4a08c95c 8980 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
f44fe430 8981 return Is_Ref_To_Bit_Packed_Slice (Prefix (N));
70482933
RK
8982
8983 else
8984 return False;
8985 end if;
8986 end Is_Ref_To_Bit_Packed_Slice;
8987
8988 -----------------------
8989 -- Is_Renamed_Object --
8990 -----------------------
8991
8992 function Is_Renamed_Object (N : Node_Id) return Boolean is
8993 Pnod : constant Node_Id := Parent (N);
8994 Kind : constant Node_Kind := Nkind (Pnod);
70482933
RK
8995 begin
8996 if Kind = N_Object_Renaming_Declaration then
8997 return True;
4a08c95c 8998 elsif Kind in N_Indexed_Component | N_Selected_Component then
70482933 8999 return Is_Renamed_Object (Pnod);
70482933
RK
9000 else
9001 return False;
9002 end if;
9003 end Is_Renamed_Object;
9004
cdc96e3e
AC
9005 --------------------------------------
9006 -- Is_Secondary_Stack_BIP_Func_Call --
9007 --------------------------------------
9008
9009 function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is
7b966a95
AC
9010 Actual : Node_Id;
9011 Call : Node_Id := Expr;
9012 Formal : Node_Id;
9013 Param : Node_Id;
cdc96e3e
AC
9014
9015 begin
e0adfeb4
AC
9016 -- Build-in-place calls usually appear in 'reference format. Note that
9017 -- the accessibility check machinery may add an extra 'reference due to
9018 -- side effect removal.
cdc96e3e 9019
e0adfeb4 9020 while Nkind (Call) = N_Reference loop
cdc96e3e 9021 Call := Prefix (Call);
e0adfeb4 9022 end loop;
cdc96e3e 9023
0691ed6b 9024 Call := Unqual_Conv (Call);
cdc96e3e
AC
9025
9026 if Is_Build_In_Place_Function_Call (Call) then
cdc96e3e 9027
7b966a95 9028 -- Examine all parameter associations of the function call
cdc96e3e 9029
7b966a95
AC
9030 Param := First (Parameter_Associations (Call));
9031 while Present (Param) loop
d4dfb005 9032 if Nkind (Param) = N_Parameter_Association then
7b966a95
AC
9033 Formal := Selector_Name (Param);
9034 Actual := Explicit_Actual_Parameter (Param);
9035
7b966a95 9036 -- A match for BIPalloc => 2 has been found
cdc96e3e 9037
b93d80bc
JM
9038 if Is_Build_In_Place_Entity (Formal)
9039 and then BIP_Suffix_Kind (Formal) = BIP_Alloc_Form
7b966a95
AC
9040 and then Nkind (Actual) = N_Integer_Literal
9041 and then Intval (Actual) = Uint_2
9042 then
9043 return True;
cdc96e3e 9044 end if;
7b966a95 9045 end if;
cdc96e3e 9046
7b966a95
AC
9047 Next (Param);
9048 end loop;
cdc96e3e
AC
9049 end if;
9050
9051 return False;
9052 end Is_Secondary_Stack_BIP_Func_Call;
9053
aab08130
AC
9054 -------------------------------------
9055 -- Is_Tag_To_Class_Wide_Conversion --
9056 -------------------------------------
2d395256 9057
aab08130
AC
9058 function Is_Tag_To_Class_Wide_Conversion
9059 (Obj_Id : Entity_Id) return Boolean
9060 is
2d395256
AC
9061 Expr : constant Node_Id := Expression (Parent (Obj_Id));
9062
9063 begin
9064 return
9065 Is_Class_Wide_Type (Etype (Obj_Id))
9066 and then Present (Expr)
9067 and then Nkind (Expr) = N_Unchecked_Type_Conversion
3477e0b2 9068 and then Is_RTE (Etype (Expression (Expr)), RE_Tag);
aab08130 9069 end Is_Tag_To_Class_Wide_Conversion;
2d395256 9070
a46fa651
ES
9071 --------------------------------
9072 -- Is_Uninitialized_Aggregate --
9073 --------------------------------
9074
9075 function Is_Uninitialized_Aggregate
9076 (Exp : Node_Id;
9077 T : Entity_Id) return Boolean
9078 is
9079 Comp : Node_Id;
9080 Comp_Type : Entity_Id;
9081 Typ : Entity_Id;
9082
9083 begin
9084 if Nkind (Exp) /= N_Aggregate then
9085 return False;
9086 end if;
9087
9088 Preanalyze_And_Resolve (Exp, T);
9089 Typ := Etype (Exp);
9090
9091 if No (Typ)
9092 or else Ekind (Typ) /= E_Array_Subtype
9093 or else Present (Expressions (Exp))
9094 or else No (Component_Associations (Exp))
9095 then
9096 return False;
9097 else
9098 Comp_Type := Component_Type (Typ);
9099 Comp := First (Component_Associations (Exp));
9100
9101 if not Box_Present (Comp)
9102 or else Present (Next (Comp))
9103 then
9104 return False;
9105 end if;
9106
9107 return Is_Scalar_Type (Comp_Type)
9108 and then No (Default_Aspect_Component_Value (Typ));
9109 end if;
9110 end Is_Uninitialized_Aggregate;
9111
70482933
RK
9112 ----------------------------
9113 -- Is_Untagged_Derivation --
9114 ----------------------------
9115
9116 function Is_Untagged_Derivation (T : Entity_Id) return Boolean is
9117 begin
9118 return (not Is_Tagged_Type (T) and then Is_Derived_Type (T))
9119 or else
7b966a95
AC
9120 (Is_Private_Type (T) and then Present (Full_View (T))
9121 and then not Is_Tagged_Type (Full_View (T))
9122 and then Is_Derived_Type (Full_View (T))
9123 and then Etype (Full_View (T)) /= T);
70482933
RK
9124 end Is_Untagged_Derivation;
9125
51148dda
AC
9126 ------------------------------------
9127 -- Is_Untagged_Private_Derivation --
9128 ------------------------------------
9129
9130 function Is_Untagged_Private_Derivation
9131 (Priv_Typ : Entity_Id;
9132 Full_Typ : Entity_Id) return Boolean
9133 is
9134 begin
9135 return
9136 Present (Priv_Typ)
9137 and then Is_Untagged_Derivation (Priv_Typ)
9138 and then Is_Private_Type (Etype (Priv_Typ))
9139 and then Present (Full_Typ)
9140 and then Is_Itype (Full_Typ);
9141 end Is_Untagged_Private_Derivation;
9142
b3801819
PMR
9143 ------------------------------
9144 -- Is_Verifiable_DIC_Pragma --
9145 ------------------------------
9146
9147 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is
9148 Args : constant List_Id := Pragma_Argument_Associations (Prag);
9149
9150 begin
9151 -- To qualify as verifiable, a DIC pragma must have a non-null argument
9152
9153 return
9154 Present (Args)
f7937111
GD
9155
9156 -- If there are args, but the first arg is Empty, then treat the
9157 -- pragma the same as having no args (there may be a second arg that
9158 -- is an implicitly added type arg, and Empty is a placeholder).
9159
9160 and then Present (Get_Pragma_Arg (First (Args)))
9161
b3801819
PMR
9162 and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null;
9163 end Is_Verifiable_DIC_Pragma;
9164
65df5b71
HK
9165 ---------------------------
9166 -- Is_Volatile_Reference --
9167 ---------------------------
9168
9169 function Is_Volatile_Reference (N : Node_Id) return Boolean is
9170 begin
bb012790
AC
9171 -- Only source references are to be treated as volatile, internally
9172 -- generated stuff cannot have volatile external effects.
9173
9174 if not Comes_From_Source (N) then
9175 return False;
9176
9177 -- Never true for reference to a type
9178
9179 elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then
9180 return False;
9181
57d08392
AC
9182 -- Never true for a compile time known constant
9183
9184 elsif Compile_Time_Known_Value (N) then
9185 return False;
9186
bb012790
AC
9187 -- True if object reference with volatile type
9188
76f9c7f4 9189 elsif Is_Volatile_Object_Ref (N) then
65df5b71
HK
9190 return True;
9191
bb012790
AC
9192 -- True if reference to volatile entity
9193
65df5b71
HK
9194 elsif Is_Entity_Name (N) then
9195 return Treat_As_Volatile (Entity (N));
9196
bb012790
AC
9197 -- True for slice of volatile array
9198
65df5b71
HK
9199 elsif Nkind (N) = N_Slice then
9200 return Is_Volatile_Reference (Prefix (N));
9201
bb012790
AC
9202 -- True if volatile component
9203
4a08c95c 9204 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
65df5b71 9205 if (Is_Entity_Name (Prefix (N))
0e564ab4 9206 and then Has_Volatile_Components (Entity (Prefix (N))))
65df5b71 9207 or else (Present (Etype (Prefix (N)))
0e564ab4 9208 and then Has_Volatile_Components (Etype (Prefix (N))))
65df5b71
HK
9209 then
9210 return True;
9211 else
9212 return Is_Volatile_Reference (Prefix (N));
9213 end if;
9214
bb012790
AC
9215 -- Otherwise false
9216
65df5b71
HK
9217 else
9218 return False;
9219 end if;
9220 end Is_Volatile_Reference;
9221
70482933
RK
9222 --------------------
9223 -- Kill_Dead_Code --
9224 --------------------
9225
05350ac6 9226 procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is
3acdda2d
AC
9227 W : Boolean := Warn;
9228 -- Set False if warnings suppressed
9229
70482933
RK
9230 begin
9231 if Present (N) then
70482933
RK
9232 Remove_Warning_Messages (N);
9233
90e491a7
PMR
9234 -- Update the internal structures of the ABE mechanism in case the
9235 -- dead node is an elaboration scenario.
9236
9237 Kill_Elaboration_Scenario (N);
9238
3acdda2d
AC
9239 -- Generate warning if appropriate
9240
9241 if W then
9242
9243 -- We suppress the warning if this code is under control of an
9244 -- if statement, whose condition is a simple identifier, and
9245 -- either we are in an instance, or warnings off is set for this
9246 -- identifier. The reason for killing it in the instance case is
9247 -- that it is common and reasonable for code to be deleted in
9248 -- instances for various reasons.
9249
02bb0765
AC
9250 -- Could we use Is_Statically_Unevaluated here???
9251
3acdda2d
AC
9252 if Nkind (Parent (N)) = N_If_Statement then
9253 declare
9254 C : constant Node_Id := Condition (Parent (N));
9255 begin
9256 if Nkind (C) = N_Identifier
9257 and then
9258 (In_Instance
9259 or else (Present (Entity (C))
0e564ab4 9260 and then Has_Warnings_Off (Entity (C))))
3acdda2d
AC
9261 then
9262 W := False;
9263 end if;
9264 end;
9265 end if;
9266
9267 -- Generate warning if not suppressed
9268
9269 if W then
ed2233dc 9270 Error_Msg_F
685bc70f 9271 ("?t?this code can never be executed and has been deleted!",
324ac540 9272 N);
3acdda2d 9273 end if;
05350ac6
BD
9274 end if;
9275
07fc65c4 9276 -- Recurse into block statements and bodies to process declarations
3acdda2d 9277 -- and statements.
70482933 9278
07fc65c4
GB
9279 if Nkind (N) = N_Block_Statement
9280 or else Nkind (N) = N_Subprogram_Body
9281 or else Nkind (N) = N_Package_Body
9282 then
569f538b
TQ
9283 Kill_Dead_Code (Declarations (N), False);
9284 Kill_Dead_Code (Statements (Handled_Statement_Sequence (N)));
70482933 9285
07fc65c4
GB
9286 if Nkind (N) = N_Subprogram_Body then
9287 Set_Is_Eliminated (Defining_Entity (N));
9288 end if;
9289
f44fe430
RD
9290 elsif Nkind (N) = N_Package_Declaration then
9291 Kill_Dead_Code (Visible_Declarations (Specification (N)));
9292 Kill_Dead_Code (Private_Declarations (Specification (N)));
9293
569f538b 9294 -- ??? After this point, Delete_Tree has been called on all
273adcdf
AC
9295 -- declarations in Specification (N), so references to entities
9296 -- therein look suspicious.
569f538b 9297
f44fe430
RD
9298 declare
9299 E : Entity_Id := First_Entity (Defining_Entity (N));
02bb0765 9300
f44fe430
RD
9301 begin
9302 while Present (E) loop
9303 if Ekind (E) = E_Operator then
9304 Set_Is_Eliminated (E);
9305 end if;
9306
9307 Next_Entity (E);
9308 end loop;
9309 end;
9310
273adcdf
AC
9311 -- Recurse into composite statement to kill individual statements in
9312 -- particular instantiations.
70482933
RK
9313
9314 elsif Nkind (N) = N_If_Statement then
9315 Kill_Dead_Code (Then_Statements (N));
02bb0765 9316 Kill_Dead_Code (Elsif_Parts (N));
70482933
RK
9317 Kill_Dead_Code (Else_Statements (N));
9318
9319 elsif Nkind (N) = N_Loop_Statement then
9320 Kill_Dead_Code (Statements (N));
9321
9322 elsif Nkind (N) = N_Case_Statement then
9323 declare
bebbff91 9324 Alt : Node_Id;
70482933 9325 begin
bebbff91 9326 Alt := First (Alternatives (N));
70482933
RK
9327 while Present (Alt) loop
9328 Kill_Dead_Code (Statements (Alt));
9329 Next (Alt);
9330 end loop;
9331 end;
9332
fbf5a39b
AC
9333 elsif Nkind (N) = N_Case_Statement_Alternative then
9334 Kill_Dead_Code (Statements (N));
9335
70482933
RK
9336 -- Deal with dead instances caused by deleting instantiations
9337
9338 elsif Nkind (N) in N_Generic_Instantiation then
9339 Remove_Dead_Instance (N);
9340 end if;
70482933
RK
9341 end if;
9342 end Kill_Dead_Code;
9343
9344 -- Case where argument is a list of nodes to be killed
9345
05350ac6 9346 procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is
70482933 9347 N : Node_Id;
05350ac6 9348 W : Boolean;
02bb0765 9349
70482933 9350 begin
05350ac6 9351 W := Warn;
02bb0765 9352
70482933 9353 if Is_Non_Empty_List (L) then
ac4d6407
RD
9354 N := First (L);
9355 while Present (N) loop
05350ac6
BD
9356 Kill_Dead_Code (N, W);
9357 W := False;
ac4d6407 9358 Next (N);
70482933
RK
9359 end loop;
9360 end if;
9361 end Kill_Dead_Code;
9362
70482933
RK
9363 -----------------------------
9364 -- Make_CW_Equivalent_Type --
9365 -----------------------------
9366
6fb4cdde
AC
9367 -- Create a record type used as an equivalent of any member of the class
9368 -- which takes its size from exp.
70482933
RK
9369
9370 -- Generate the following code:
9371
9372 -- type Equiv_T is record
52ba224d 9373 -- _parent : T (List of discriminant constraints taken from Exp);
fbf5a39b 9374 -- Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8);
70482933 9375 -- end Equiv_T;
fbf5a39b 9376 --
52ba224d
TQ
9377 -- ??? Note that this type does not guarantee same alignment as all
9378 -- derived types
9379 --
9380 -- Note: for the freezing circuitry, this looks like a record extension,
9381 -- and so we need to make sure that the scalar storage order is the same
9382 -- as that of the parent type. (This does not change anything for the
9383 -- representation of the extension part.)
70482933
RK
9384
9385 function Make_CW_Equivalent_Type
bebbff91
AC
9386 (T : Entity_Id;
9387 E : Node_Id) return Entity_Id
70482933
RK
9388 is
9389 Loc : constant Source_Ptr := Sloc (E);
9390 Root_Typ : constant Entity_Id := Root_Type (T);
52ba224d 9391 Root_Utyp : constant Entity_Id := Underlying_Type (Root_Typ);
fbf5a39b 9392 List_Def : constant List_Id := Empty_List;
0712790c 9393 Comp_List : constant List_Id := New_List;
70482933
RK
9394 Equiv_Type : Entity_Id;
9395 Range_Type : Entity_Id;
9396 Str_Type : Entity_Id;
70482933
RK
9397 Constr_Root : Entity_Id;
9398 Sizexpr : Node_Id;
9399
9400 begin
3e2399ba
AC
9401 -- If the root type is already constrained, there are no discriminants
9402 -- in the expression.
9403
9404 if not Has_Discriminants (Root_Typ)
9405 or else Is_Constrained (Root_Typ)
9406 then
70482933 9407 Constr_Root := Root_Typ;
ed09416f 9408
3f833dc2 9409 -- At this point in the expansion, nonlimited view of the type
ed09416f
AC
9410 -- must be available, otherwise the error will be reported later.
9411
9412 if From_Limited_With (Constr_Root)
9413 and then Present (Non_Limited_View (Constr_Root))
9414 then
9415 Constr_Root := Non_Limited_View (Constr_Root);
9416 end if;
9417
70482933 9418 else
092ef350 9419 Constr_Root := Make_Temporary (Loc, 'R');
70482933
RK
9420
9421 -- subtype cstr__n is T (List of discr constraints taken from Exp)
9422
9423 Append_To (List_Def,
9424 Make_Subtype_Declaration (Loc,
9425 Defining_Identifier => Constr_Root,
092ef350 9426 Subtype_Indication => Make_Subtype_From_Expr (E, Root_Typ)));
70482933
RK
9427 end if;
9428
0712790c 9429 -- Generate the range subtype declaration
70482933 9430
092ef350 9431 Range_Type := Make_Temporary (Loc, 'G');
70482933 9432
0712790c 9433 if not Is_Interface (Root_Typ) then
6fb4cdde 9434
0712790c
ES
9435 -- subtype rg__xx is
9436 -- Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit
9437
9438 Sizexpr :=
9439 Make_Op_Subtract (Loc,
9440 Left_Opnd =>
9441 Make_Attribute_Reference (Loc,
9442 Prefix =>
9443 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9444 Attribute_Name => Name_Size),
9445 Right_Opnd =>
9446 Make_Attribute_Reference (Loc,
e4494292 9447 Prefix => New_Occurrence_Of (Constr_Root, Loc),
0712790c
ES
9448 Attribute_Name => Name_Object_Size));
9449 else
9450 -- subtype rg__xx is
9451 -- Storage_Offset range 1 .. Expr'size / Storage_Unit
9452
9453 Sizexpr :=
9454 Make_Attribute_Reference (Loc,
9455 Prefix =>
9456 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)),
9457 Attribute_Name => Name_Size);
9458 end if;
70482933
RK
9459
9460 Set_Paren_Count (Sizexpr, 1);
9461
9462 Append_To (List_Def,
9463 Make_Subtype_Declaration (Loc,
9464 Defining_Identifier => Range_Type,
9465 Subtype_Indication =>
9466 Make_Subtype_Indication (Loc,
e4494292 9467 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
70482933
RK
9468 Constraint => Make_Range_Constraint (Loc,
9469 Range_Expression =>
9470 Make_Range (Loc,
9471 Low_Bound => Make_Integer_Literal (Loc, 1),
9472 High_Bound =>
9473 Make_Op_Divide (Loc,
9474 Left_Opnd => Sizexpr,
9475 Right_Opnd => Make_Integer_Literal (Loc,
9476 Intval => System_Storage_Unit)))))));
9477
9478 -- subtype str__nn is Storage_Array (rg__x);
9479
092ef350 9480 Str_Type := Make_Temporary (Loc, 'S');
70482933
RK
9481 Append_To (List_Def,
9482 Make_Subtype_Declaration (Loc,
9483 Defining_Identifier => Str_Type,
9484 Subtype_Indication =>
9485 Make_Subtype_Indication (Loc,
e4494292 9486 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc),
70482933
RK
9487 Constraint =>
9488 Make_Index_Or_Discriminant_Constraint (Loc,
9489 Constraints =>
e4494292 9490 New_List (New_Occurrence_Of (Range_Type, Loc))))));
70482933
RK
9491
9492 -- type Equiv_T is record
0712790c 9493 -- [ _parent : Tnn; ]
70482933
RK
9494 -- E : Str_Type;
9495 -- end Equiv_T;
9496
092ef350 9497 Equiv_Type := Make_Temporary (Loc, 'T');
70482933
RK
9498 Set_Ekind (Equiv_Type, E_Record_Type);
9499 Set_Parent_Subtype (Equiv_Type, Constr_Root);
9500
80fa4617
EB
9501 -- Set Is_Class_Wide_Equivalent_Type very early to trigger the special
9502 -- treatment for this type. In particular, even though _parent's type
9503 -- is a controlled type or contains controlled components, we do not
9504 -- want to set Has_Controlled_Component on it to avoid making it gain
9505 -- an unwanted _controller component.
9506
9507 Set_Is_Class_Wide_Equivalent_Type (Equiv_Type);
9508
f3296dd3 9509 -- A class-wide equivalent type does not require initialization
3dddb11e
ES
9510
9511 Set_Suppress_Initialization (Equiv_Type);
9512
0712790c
ES
9513 if not Is_Interface (Root_Typ) then
9514 Append_To (Comp_List,
9515 Make_Component_Declaration (Loc,
3dddb11e 9516 Defining_Identifier =>
0712790c
ES
9517 Make_Defining_Identifier (Loc, Name_uParent),
9518 Component_Definition =>
9519 Make_Component_Definition (Loc,
9520 Aliased_Present => False,
e4494292 9521 Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc))));
52ba224d 9522
dd81163f
HK
9523 Set_Reverse_Storage_Order
9524 (Equiv_Type, Reverse_Storage_Order (Base_Type (Root_Utyp)));
9525 Set_Reverse_Bit_Order
9526 (Equiv_Type, Reverse_Bit_Order (Base_Type (Root_Utyp)));
0712790c
ES
9527 end if;
9528
9529 Append_To (Comp_List,
9530 Make_Component_Declaration (Loc,
092ef350 9531 Defining_Identifier => Make_Temporary (Loc, 'C'),
0712790c
ES
9532 Component_Definition =>
9533 Make_Component_Definition (Loc,
9534 Aliased_Present => False,
e4494292 9535 Subtype_Indication => New_Occurrence_Of (Str_Type, Loc))));
0712790c 9536
70482933
RK
9537 Append_To (List_Def,
9538 Make_Full_Type_Declaration (Loc,
9539 Defining_Identifier => Equiv_Type,
3dddb11e 9540 Type_Definition =>
70482933 9541 Make_Record_Definition (Loc,
3dddb11e 9542 Component_List =>
0712790c
ES
9543 Make_Component_List (Loc,
9544 Component_Items => Comp_List,
9545 Variant_Part => Empty))));
9546
273adcdf
AC
9547 -- Suppress all checks during the analysis of the expanded code to avoid
9548 -- the generation of spurious warnings under ZFP run-time.
0712790c
ES
9549
9550 Insert_Actions (E, List_Def, Suppress => All_Checks);
70482933
RK
9551 return Equiv_Type;
9552 end Make_CW_Equivalent_Type;
9553
e606088a
AC
9554 -------------------------
9555 -- Make_Invariant_Call --
9556 -------------------------
9557
9558 function Make_Invariant_Call (Expr : Node_Id) return Node_Id is
d65a80fd
HK
9559 Loc : constant Source_Ptr := Sloc (Expr);
9560 Typ : constant Entity_Id := Base_Type (Etype (Expr));
3ddfabe3 9561 pragma Assert (Has_Invariants (Typ));
b9daf13c 9562 Proc_Id : constant Entity_Id := Invariant_Procedure (Typ);
3ddfabe3 9563 pragma Assert (Present (Proc_Id));
b9daf13c
BD
9564 begin
9565 -- The invariant procedure has a null body if assertions are disabled or
9566 -- Assertion_Policy Ignore is in effect. In that case, generate a null
9567 -- statement instead of a call to the invariant procedure.
2995860f 9568
b9daf13c
BD
9569 if Has_Null_Body (Proc_Id) then
9570 return Make_Null_Statement (Loc);
9571 else
9572 return
9573 Make_Procedure_Call_Statement (Loc,
9574 Name => New_Occurrence_Of (Proc_Id, Loc),
9575 Parameter_Associations => New_List (Relocate_Node (Expr)));
9576 end if;
e606088a
AC
9577 end Make_Invariant_Call;
9578
70482933
RK
9579 ------------------------
9580 -- Make_Literal_Range --
9581 ------------------------
9582
9583 function Make_Literal_Range
9584 (Loc : Source_Ptr;
bebbff91 9585 Literal_Typ : Entity_Id) return Node_Id
70482933 9586 is
86cde7b1
RD
9587 Lo : constant Node_Id :=
9588 New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ));
9589 Index : constant Entity_Id := Etype (Lo);
86cde7b1
RD
9590 Length_Expr : constant Node_Id :=
9591 Make_Op_Subtract (Loc,
90e491a7 9592 Left_Opnd =>
86cde7b1
RD
9593 Make_Integer_Literal (Loc,
9594 Intval => String_Literal_Length (Literal_Typ)),
90e491a7
PMR
9595 Right_Opnd => Make_Integer_Literal (Loc, 1));
9596
9597 Hi : Node_Id;
f91b40db 9598
70482933 9599 begin
f91b40db
GB
9600 Set_Analyzed (Lo, False);
9601
90e491a7
PMR
9602 if Is_Integer_Type (Index) then
9603 Hi :=
9604 Make_Op_Add (Loc,
9605 Left_Opnd => New_Copy_Tree (Lo),
9606 Right_Opnd => Length_Expr);
9607 else
9608 Hi :=
9609 Make_Attribute_Reference (Loc,
9610 Attribute_Name => Name_Val,
9611 Prefix => New_Occurrence_Of (Index, Loc),
9612 Expressions => New_List (
9613 Make_Op_Add (Loc,
9614 Left_Opnd =>
9615 Make_Attribute_Reference (Loc,
9616 Attribute_Name => Name_Pos,
9617 Prefix => New_Occurrence_Of (Index, Loc),
9618 Expressions => New_List (New_Copy_Tree (Lo))),
9619 Right_Opnd => Length_Expr)));
9620 end if;
86cde7b1 9621
90e491a7
PMR
9622 return
9623 Make_Range (Loc,
9624 Low_Bound => Lo,
9625 High_Bound => Hi);
70482933
RK
9626 end Make_Literal_Range;
9627
b3b9865d
AC
9628 --------------------------
9629 -- Make_Non_Empty_Check --
9630 --------------------------
9631
9632 function Make_Non_Empty_Check
9633 (Loc : Source_Ptr;
9634 N : Node_Id) return Node_Id
9635 is
9636 begin
9637 return
9638 Make_Op_Ne (Loc,
9639 Left_Opnd =>
9640 Make_Attribute_Reference (Loc,
9641 Attribute_Name => Name_Length,
9642 Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)),
9643 Right_Opnd =>
9644 Make_Integer_Literal (Loc, 0));
9645 end Make_Non_Empty_Check;
9646
4818e7b9
RD
9647 -------------------------
9648 -- Make_Predicate_Call --
9649 -------------------------
9650
b0bf18ad
AC
9651 -- WARNING: This routine manages Ghost regions. Return statements must be
9652 -- replaced by gotos which jump to the end of the routine and restore the
9653 -- Ghost mode.
9654
4818e7b9
RD
9655 function Make_Predicate_Call
9656 (Typ : Entity_Id;
fc142f63
AC
9657 Expr : Node_Id;
9658 Mem : Boolean := False) return Node_Id
4818e7b9 9659 is
d65a80fd 9660 Loc : constant Source_Ptr := Sloc (Expr);
241ebe89 9661
9057bd6a
HK
9662 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode;
9663 Saved_IGR : constant Node_Id := Ignored_Ghost_Region;
9664 -- Save the Ghost-related attributes to restore on exit
f9a8f910 9665
d65a80fd
HK
9666 Call : Node_Id;
9667 Func_Id : Entity_Id;
4818e7b9
RD
9668
9669 begin
ffdd5248
ES
9670 Func_Id := Predicate_Function (Typ);
9671 pragma Assert (Present (Func_Id));
4818e7b9 9672
1af4455a
HK
9673 -- The related type may be subject to pragma Ghost. Set the mode now to
9674 -- ensure that the call is properly marked as Ghost.
241ebe89 9675
f9a8f910 9676 Set_Ghost_Mode (Typ);
241ebe89 9677
fc142f63
AC
9678 -- Call special membership version if requested and available
9679
d65a80fd
HK
9680 if Mem and then Present (Predicate_Function_M (Typ)) then
9681 Func_Id := Predicate_Function_M (Typ);
fc142f63
AC
9682 end if;
9683
9684 -- Case of calling normal predicate function
9685
98b779ae
PMR
9686 -- If the type is tagged, the expression may be class-wide, in which
9687 -- case it has to be converted to its root type, given that the
c7862167
HK
9688 -- generated predicate function is not dispatching. The conversion is
9689 -- type-safe and does not need validation, which matters when private
9690 -- extensions are involved.
98b779ae
PMR
9691
9692 if Is_Tagged_Type (Typ) then
9693 Call :=
9694 Make_Function_Call (Loc,
9695 Name => New_Occurrence_Of (Func_Id, Loc),
9696 Parameter_Associations =>
6cd1ee98 9697 New_List (OK_Convert_To (Typ, Relocate_Node (Expr))));
98b779ae
PMR
9698 else
9699 Call :=
9700 Make_Function_Call (Loc,
9701 Name => New_Occurrence_Of (Func_Id, Loc),
9702 Parameter_Associations => New_List (Relocate_Node (Expr)));
9703 end if;
241ebe89 9704
9057bd6a 9705 Restore_Ghost_Region (Saved_GM, Saved_IGR);
f9a8f910 9706
241ebe89 9707 return Call;
4818e7b9
RD
9708 end Make_Predicate_Call;
9709
9710 --------------------------
9711 -- Make_Predicate_Check --
9712 --------------------------
9713
9714 function Make_Predicate_Check
9715 (Typ : Entity_Id;
9716 Expr : Node_Id) return Node_Id
9717 is
80631298 9718 Loc : constant Source_Ptr := Sloc (Expr);
88fa9a24 9719
80631298
HK
9720 procedure Add_Failure_Expression (Args : List_Id);
9721 -- Add the failure expression of pragma Predicate_Failure (if any) to
9722 -- list Args.
9723
9724 ----------------------------
9725 -- Add_Failure_Expression --
9726 ----------------------------
9727
9728 procedure Add_Failure_Expression (Args : List_Id) is
9729 function Failure_Expression return Node_Id;
9730 pragma Inline (Failure_Expression);
9731 -- Find aspect or pragma Predicate_Failure that applies to type Typ
9732 -- and return its expression. Return Empty if no such annotation is
9733 -- available.
9734
9735 function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean;
9736 pragma Inline (Is_OK_PF_Aspect);
9737 -- Determine whether aspect Asp is a suitable Predicate_Failure
9738 -- aspect that applies to type Typ.
9739
9740 function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean;
9741 pragma Inline (Is_OK_PF_Pragma);
9742 -- Determine whether pragma Prag is a suitable Predicate_Failure
9743 -- pragma that applies to type Typ.
9744
9745 procedure Replace_Subtype_Reference (N : Node_Id);
9746 -- Replace the current instance of type Typ denoted by N with
9747 -- expression Expr.
9748
9749 ------------------------
9750 -- Failure_Expression --
9751 ------------------------
9752
9753 function Failure_Expression return Node_Id is
9754 Item : Node_Id;
9755
9756 begin
9757 -- The management of the rep item chain involves "inheritance" of
9758 -- parent type chains. If a parent [sub]type is already subject to
9759 -- pragma Predicate_Failure, then the pragma will also appear in
9760 -- the chain of the child [sub]type, which in turn may possess a
9761 -- pragma of its own. Avoid order-dependent issues by inspecting
9762 -- the rep item chain directly. Note that routine Get_Pragma may
9763 -- return a parent pragma.
9764
9765 Item := First_Rep_Item (Typ);
9766 while Present (Item) loop
9767
9768 -- Predicate_Failure appears as an aspect
9769
9770 if Nkind (Item) = N_Aspect_Specification
9771 and then Is_OK_PF_Aspect (Item)
9772 then
9773 return Expression (Item);
9774
9775 -- Predicate_Failure appears as a pragma
9776
9777 elsif Nkind (Item) = N_Pragma
9778 and then Is_OK_PF_Pragma (Item)
9779 then
9780 return
9781 Get_Pragma_Arg
9782 (Next (First (Pragma_Argument_Associations (Item))));
9783 end if;
9784
99859ea7 9785 Next_Rep_Item (Item);
80631298
HK
9786 end loop;
9787
9788 return Empty;
9789 end Failure_Expression;
9790
9791 ---------------------
9792 -- Is_OK_PF_Aspect --
9793 ---------------------
9794
9795 function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean is
9796 begin
9797 -- To qualify, the aspect must apply to the type subjected to the
9798 -- predicate check.
9799
9800 return
9801 Chars (Identifier (Asp)) = Name_Predicate_Failure
9802 and then Present (Entity (Asp))
9803 and then Entity (Asp) = Typ;
9804 end Is_OK_PF_Aspect;
9805
9806 ---------------------
9807 -- Is_OK_PF_Pragma --
9808 ---------------------
9809
9810 function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean is
9811 Args : constant List_Id := Pragma_Argument_Associations (Prag);
9812 Typ_Arg : Node_Id;
9813
9814 begin
9815 -- Nothing to do when the pragma does not denote Predicate_Failure
9816
9817 if Pragma_Name (Prag) /= Name_Predicate_Failure then
9818 return False;
9819
9820 -- Nothing to do when the pragma lacks arguments, in which case it
9821 -- is illegal.
9822
9823 elsif No (Args) or else Is_Empty_List (Args) then
9824 return False;
9825 end if;
9826
9827 Typ_Arg := Get_Pragma_Arg (First (Args));
9828
9829 -- To qualify, the local name argument of the pragma must denote
9830 -- the type subjected to the predicate check.
9831
9832 return
9833 Is_Entity_Name (Typ_Arg)
9834 and then Present (Entity (Typ_Arg))
9835 and then Entity (Typ_Arg) = Typ;
9836 end Is_OK_PF_Pragma;
9837
9838 --------------------------------
9839 -- Replace_Subtype_Reference --
9840 --------------------------------
9841
9842 procedure Replace_Subtype_Reference (N : Node_Id) is
9843 begin
9844 Rewrite (N, New_Copy_Tree (Expr));
80631298
HK
9845 end Replace_Subtype_Reference;
9846
9847 procedure Replace_Subtype_References is
9848 new Replace_Type_References_Generic (Replace_Subtype_Reference);
9849
9850 -- Local variables
9851
9852 PF_Expr : constant Node_Id := Failure_Expression;
9853 Expr : Node_Id;
9854
9855 -- Start of processing for Add_Failure_Expression
88fa9a24 9856
88fa9a24 9857 begin
80631298 9858 if Present (PF_Expr) then
88fa9a24 9859
80631298
HK
9860 -- Replace any occurrences of the current instance of the type
9861 -- with the object subjected to the predicate check.
88fa9a24 9862
80631298
HK
9863 Expr := New_Copy_Tree (PF_Expr);
9864 Replace_Subtype_References (Expr, Typ);
88fa9a24 9865
80631298
HK
9866 -- The failure expression appears as the third argument of the
9867 -- Check pragma.
9868
9869 Append_To (Args,
9870 Make_Pragma_Argument_Association (Loc,
9871 Expression => Expr));
9872 end if;
9873 end Add_Failure_Expression;
88fa9a24
ES
9874
9875 -- Local variables
9876
80631298
HK
9877 Args : List_Id;
9878 Nam : Name_Id;
88fa9a24
ES
9879
9880 -- Start of processing for Make_Predicate_Check
4818e7b9
RD
9881
9882 begin
48bb06a7
AC
9883 -- If predicate checks are suppressed, then return a null statement. For
9884 -- this call, we check only the scope setting. If the caller wants to
9885 -- check a specific entity's setting, they must do it manually.
f1c80977
AC
9886
9887 if Predicate_Checks_Suppressed (Empty) then
9888 return Make_Null_Statement (Loc);
9889 end if;
9890
152f64c2 9891 -- Do not generate a check within stream functions and the like.
8e1e62e3 9892
152f64c2 9893 if not Predicate_Check_In_Scope (Expr) then
8e1e62e3
AC
9894 return Make_Null_Statement (Loc);
9895 end if;
9896
aab45d22 9897 -- Compute proper name to use, we need to get this right so that the
16d3a853 9898 -- right set of check policies apply to the Check pragma we are making.
aab45d22
AC
9899
9900 if Has_Dynamic_Predicate_Aspect (Typ) then
9901 Nam := Name_Dynamic_Predicate;
9902 elsif Has_Static_Predicate_Aspect (Typ) then
9903 Nam := Name_Static_Predicate;
9904 else
9905 Nam := Name_Predicate;
9906 end if;
9907
80631298 9908 Args := New_List (
a2c314c7
AC
9909 Make_Pragma_Argument_Association (Loc,
9910 Expression => Make_Identifier (Loc, Nam)),
9911 Make_Pragma_Argument_Association (Loc,
9912 Expression => Make_Predicate_Call (Typ, Expr)));
9913
80631298
HK
9914 -- If the subtype is subject to pragma Predicate_Failure, add the
9915 -- failure expression as an additional parameter.
88fa9a24 9916
80631298 9917 Add_Failure_Expression (Args);
a2c314c7 9918
4818e7b9
RD
9919 return
9920 Make_Pragma (Loc,
533e3abc 9921 Chars => Name_Check,
80631298 9922 Pragma_Argument_Associations => Args);
4818e7b9
RD
9923 end Make_Predicate_Check;
9924
70482933
RK
9925 ----------------------------
9926 -- Make_Subtype_From_Expr --
9927 ----------------------------
9928
e14c931f
RW
9929 -- 1. If Expr is an unconstrained array expression, creates
9930 -- Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n))
70482933
RK
9931
9932 -- 2. If Expr is a unconstrained discriminated type expression, creates
9933 -- Unc_Type(Expr.Discr1, ... , Expr.Discr_n)
9934
f3296dd3 9935 -- 3. If Expr is class-wide, creates an implicit class-wide subtype
70482933
RK
9936
9937 function Make_Subtype_From_Expr
d9307840
HK
9938 (E : Node_Id;
9939 Unc_Typ : Entity_Id;
9940 Related_Id : Entity_Id := Empty) return Node_Id
70482933 9941 is
fbf5a39b 9942 List_Constr : constant List_Id := New_List;
d18b1548 9943 Loc : constant Source_Ptr := Sloc (E);
70482933 9944 D : Entity_Id;
d18b1548
AC
9945 Full_Exp : Node_Id;
9946 Full_Subtyp : Entity_Id;
9947 High_Bound : Entity_Id;
9948 Index_Typ : Entity_Id;
9949 Low_Bound : Entity_Id;
9950 Priv_Subtyp : Entity_Id;
9951 Utyp : Entity_Id;
70482933
RK
9952
9953 begin
9954 if Is_Private_Type (Unc_Typ)
9955 and then Has_Unknown_Discriminants (Unc_Typ)
9956 then
2f54ef3d
AC
9957 -- The caller requests a unique external name for both the private
9958 -- and the full subtype.
d9307840
HK
9959
9960 if Present (Related_Id) then
9961 Full_Subtyp :=
9962 Make_Defining_Identifier (Loc,
9963 Chars => New_External_Name (Chars (Related_Id), 'C'));
9964 Priv_Subtyp :=
9965 Make_Defining_Identifier (Loc,
9966 Chars => New_External_Name (Chars (Related_Id), 'P'));
9967
9968 else
9969 Full_Subtyp := Make_Temporary (Loc, 'C');
9970 Priv_Subtyp := Make_Temporary (Loc, 'P');
9971 end if;
9972
d18b1548
AC
9973 -- Prepare the subtype completion. Use the base type to find the
9974 -- underlying type because the type may be a generic actual or an
9975 -- explicit subtype.
70482933 9976
d9307840
HK
9977 Utyp := Underlying_Type (Base_Type (Unc_Typ));
9978
9979 Full_Exp :=
092ef350 9980 Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E));
70482933
RK
9981 Set_Parent (Full_Exp, Parent (E));
9982
70482933
RK
9983 Insert_Action (E,
9984 Make_Subtype_Declaration (Loc,
9985 Defining_Identifier => Full_Subtyp,
9986 Subtype_Indication => Make_Subtype_From_Expr (Full_Exp, Utyp)));
9987
9988 -- Define the dummy private subtype
9989
9990 Set_Ekind (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ)));
ea985d95 9991 Set_Etype (Priv_Subtyp, Base_Type (Unc_Typ));
70482933
RK
9992 Set_Scope (Priv_Subtyp, Full_Subtyp);
9993 Set_Is_Constrained (Priv_Subtyp);
9994 Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ));
9995 Set_Is_Itype (Priv_Subtyp);
9996 Set_Associated_Node_For_Itype (Priv_Subtyp, E);
9997
9998 if Is_Tagged_Type (Priv_Subtyp) then
9999 Set_Class_Wide_Type
10000 (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ));
ef2a63ba
JM
10001 Set_Direct_Primitive_Operations (Priv_Subtyp,
10002 Direct_Primitive_Operations (Unc_Typ));
70482933
RK
10003 end if;
10004
10005 Set_Full_View (Priv_Subtyp, Full_Subtyp);
10006
e4494292 10007 return New_Occurrence_Of (Priv_Subtyp, Loc);
70482933
RK
10008
10009 elsif Is_Array_Type (Unc_Typ) then
d18b1548 10010 Index_Typ := First_Index (Unc_Typ);
70482933 10011 for J in 1 .. Number_Dimensions (Unc_Typ) loop
d18b1548
AC
10012
10013 -- Capture the bounds of each index constraint in case the context
10014 -- is an object declaration of an unconstrained type initialized
10015 -- by a function call:
10016
10017 -- Obj : Unconstr_Typ := Func_Call;
10018
10019 -- This scenario requires secondary scope management and the index
10020 -- constraint cannot depend on the temporary used to capture the
10021 -- result of the function call.
10022
10023 -- SS_Mark;
10024 -- Temp : Unconstr_Typ_Ptr := Func_Call'reference;
10025 -- subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last);
10026 -- Obj : S := Temp.all;
10027 -- SS_Release; -- Temp is gone at this point, bounds of S are
10028 -- -- non existent.
10029
d18b1548 10030 -- Generate:
3fbbbd1e 10031 -- Low_Bound : constant Base_Type (Index_Typ) := E'First (J);
d18b1548
AC
10032
10033 Low_Bound := Make_Temporary (Loc, 'B');
10034 Insert_Action (E,
10035 Make_Object_Declaration (Loc,
10036 Defining_Identifier => Low_Bound,
10037 Object_Definition =>
10038 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
3fbbbd1e 10039 Constant_Present => True,
d18b1548 10040 Expression =>
70482933 10041 Make_Attribute_Reference (Loc,
d18b1548 10042 Prefix => Duplicate_Subexpr_No_Checks (E),
70482933 10043 Attribute_Name => Name_First,
d18b1548
AC
10044 Expressions => New_List (
10045 Make_Integer_Literal (Loc, J)))));
8cbb664e 10046
d18b1548 10047 -- Generate:
3fbbbd1e 10048 -- High_Bound : constant Base_Type (Index_Typ) := E'Last (J);
d18b1548
AC
10049
10050 High_Bound := Make_Temporary (Loc, 'B');
10051 Insert_Action (E,
10052 Make_Object_Declaration (Loc,
10053 Defining_Identifier => High_Bound,
10054 Object_Definition =>
10055 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc),
3fbbbd1e 10056 Constant_Present => True,
d18b1548 10057 Expression =>
70482933 10058 Make_Attribute_Reference (Loc,
8cbb664e 10059 Prefix => Duplicate_Subexpr_No_Checks (E),
70482933
RK
10060 Attribute_Name => Name_Last,
10061 Expressions => New_List (
10062 Make_Integer_Literal (Loc, J)))));
d18b1548
AC
10063
10064 Append_To (List_Constr,
10065 Make_Range (Loc,
10066 Low_Bound => New_Occurrence_Of (Low_Bound, Loc),
10067 High_Bound => New_Occurrence_Of (High_Bound, Loc)));
10068
99859ea7 10069 Next_Index (Index_Typ);
70482933
RK
10070 end loop;
10071
10072 elsif Is_Class_Wide_Type (Unc_Typ) then
10073 declare
10074 CW_Subtype : Entity_Id;
10075 EQ_Typ : Entity_Id := Empty;
10076
10077 begin
535a8637 10078 -- A class-wide equivalent type is not needed on VM targets
0712790c 10079 -- because the VM back-ends handle the class-wide object
44d6a706 10080 -- initialization itself (and doesn't need or want the
70482933
RK
10081 -- additional intermediate type to handle the assignment).
10082
1f110335 10083 if Expander_Active and then Tagged_Type_Expansion then
22cb89b5 10084
f3296dd3
AC
10085 -- If this is the class-wide type of a completion that is a
10086 -- record subtype, set the type of the class-wide type to be
273adcdf
AC
10087 -- the full base type, for use in the expanded code for the
10088 -- equivalent type. Should this be done earlier when the
10089 -- completion is analyzed ???
22cb89b5
AC
10090
10091 if Is_Private_Type (Etype (Unc_Typ))
10092 and then
10093 Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype
10094 then
10095 Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ))));
10096 end if;
10097
70482933
RK
10098 EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E);
10099 end if;
10100
10101 CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E);
10102 Set_Equivalent_Type (CW_Subtype, EQ_Typ);
10103 Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ));
10104
10105 return New_Occurrence_Of (CW_Subtype, Loc);
10106 end;
10107
ea985d95 10108 -- Indefinite record type with discriminants
fbf5a39b 10109
70482933
RK
10110 else
10111 D := First_Discriminant (Unc_Typ);
fbf5a39b 10112 while Present (D) loop
70482933
RK
10113 Append_To (List_Constr,
10114 Make_Selected_Component (Loc,
8cbb664e 10115 Prefix => Duplicate_Subexpr_No_Checks (E),
e4494292 10116 Selector_Name => New_Occurrence_Of (D, Loc)));
70482933
RK
10117
10118 Next_Discriminant (D);
10119 end loop;
10120 end if;
10121
10122 return
10123 Make_Subtype_Indication (Loc,
e4494292 10124 Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc),
70482933
RK
10125 Constraint =>
10126 Make_Index_Or_Discriminant_Constraint (Loc,
10127 Constraints => List_Constr));
10128 end Make_Subtype_From_Expr;
10129
afa1ffd4
PT
10130 -----------------------------
10131 -- Make_Variant_Comparison --
10132 -----------------------------
10133
10134 function Make_Variant_Comparison
10135 (Loc : Source_Ptr;
10136 Mode : Name_Id;
10137 Curr_Val : Node_Id;
10138 Old_Val : Node_Id) return Node_Id
10139 is
10140 begin
10141 if Mode = Name_Increases then
10142 return Make_Op_Gt (Loc, Curr_Val, Old_Val);
10143 else pragma Assert (Mode = Name_Decreases);
10144 return Make_Op_Lt (Loc, Curr_Val, Old_Val);
10145 end if;
10146 end Make_Variant_Comparison;
10147
b619c88e
AC
10148 ---------------
10149 -- Map_Types --
10150 ---------------
e03f7ccf 10151
b619c88e 10152 procedure Map_Types (Parent_Type : Entity_Id; Derived_Type : Entity_Id) is
e03f7ccf 10153
b619c88e
AC
10154 -- NOTE: Most of the routines in Map_Types are intentionally unnested to
10155 -- avoid deep indentation of code.
e03f7ccf 10156
b619c88e
AC
10157 -- NOTE: Routines which deal with discriminant mapping operate on the
10158 -- [underlying/record] full view of various types because those views
10159 -- contain all discriminants and stored constraints.
e03f7ccf 10160
b619c88e
AC
10161 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id);
10162 -- Subsidiary to Map_Primitives. Find a primitive in the inheritance or
10163 -- overriding chain starting from Prim whose dispatching type is parent
10164 -- type Par_Typ and add a mapping between the result and primitive Prim.
e03f7ccf 10165
b619c88e
AC
10166 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id;
10167 -- Subsidiary to Map_Primitives. Return the next ancestor primitive in
10168 -- the inheritance or overriding chain of subprogram Subp. Return Empty
10169 -- if no such primitive is available.
70482933 10170
b619c88e
AC
10171 function Build_Chain
10172 (Par_Typ : Entity_Id;
10173 Deriv_Typ : Entity_Id) return Elist_Id;
10174 -- Subsidiary to Map_Discriminants. Recreate the derivation chain from
10175 -- parent type Par_Typ leading down towards derived type Deriv_Typ. The
10176 -- list has the form:
10177 --
10178 -- head tail
10179 -- v v
10180 -- <Ancestor_N> -> <Ancestor_N-1> -> <Ancestor_1> -> Deriv_Typ
10181 --
10182 -- Note that Par_Typ is not part of the resulting derivation chain
70482933 10183
b619c88e
AC
10184 function Discriminated_View (Typ : Entity_Id) return Entity_Id;
10185 -- Return the view of type Typ which could potentially contains either
10186 -- the discriminants or stored constraints of the type.
70482933 10187
b619c88e
AC
10188 function Find_Discriminant_Value
10189 (Discr : Entity_Id;
10190 Par_Typ : Entity_Id;
10191 Deriv_Typ : Entity_Id;
10192 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id;
10193 -- Subsidiary to Map_Discriminants. Find the value of discriminant Discr
10194 -- in the derivation chain starting from parent type Par_Typ leading to
10195 -- derived type Deriv_Typ. The returned value is one of the following:
10196 --
3f833dc2 10197 -- * An entity which is either a discriminant or a nondiscriminant
b619c88e
AC
10198 -- name, and renames/constraints Discr.
10199 --
10200 -- * An expression which constraints Discr
10201 --
10202 -- Typ_Elmt is an element of the derivation chain created by routine
10203 -- Build_Chain and denotes the current ancestor being examined.
70482933 10204
b619c88e
AC
10205 procedure Map_Discriminants
10206 (Par_Typ : Entity_Id;
10207 Deriv_Typ : Entity_Id);
10208 -- Map each discriminant of type Par_Typ to a meaningful constraint
10209 -- from the point of view of type Deriv_Typ.
70482933 10210
b619c88e
AC
10211 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id);
10212 -- Map each primitive of type Par_Typ to a corresponding primitive of
10213 -- type Deriv_Typ.
70482933 10214
b619c88e
AC
10215 -------------------
10216 -- Add_Primitive --
10217 -------------------
70482933 10218
b619c88e
AC
10219 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id) is
10220 Par_Prim : Entity_Id;
df3e68b1 10221
b619c88e
AC
10222 begin
10223 -- Inspect the inheritance chain through the Alias attribute and the
10224 -- overriding chain through the Overridden_Operation looking for an
10225 -- ancestor primitive with the appropriate dispatching type.
df3e68b1 10226
b619c88e
AC
10227 Par_Prim := Prim;
10228 while Present (Par_Prim) loop
10229 exit when Find_Dispatching_Type (Par_Prim) = Par_Typ;
10230 Par_Prim := Ancestor_Primitive (Par_Prim);
10231 end loop;
df3e68b1 10232
b619c88e 10233 -- Create a mapping of the form:
df3e68b1 10234
b619c88e 10235 -- parent type primitive -> derived type primitive
df3e68b1 10236
b619c88e
AC
10237 if Present (Par_Prim) then
10238 Type_Map.Set (Par_Prim, Prim);
10239 end if;
10240 end Add_Primitive;
df3e68b1 10241
b619c88e
AC
10242 ------------------------
10243 -- Ancestor_Primitive --
10244 ------------------------
28ad2460 10245
b619c88e
AC
10246 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is
10247 Inher_Prim : constant Entity_Id := Alias (Subp);
10248 Over_Prim : constant Entity_Id := Overridden_Operation (Subp);
df3e68b1 10249
b5360737 10250 begin
b619c88e 10251 -- The current subprogram overrides an ancestor primitive
df3e68b1 10252
b619c88e
AC
10253 if Present (Over_Prim) then
10254 return Over_Prim;
df3e68b1 10255
b619c88e
AC
10256 -- The current subprogram is an internally generated alias of an
10257 -- inherited ancestor primitive.
df3e68b1 10258
b619c88e
AC
10259 elsif Present (Inher_Prim) then
10260 return Inher_Prim;
df3e68b1 10261
b619c88e
AC
10262 -- Otherwise the current subprogram is the root of the inheritance or
10263 -- overriding chain.
b5360737 10264
28ad2460 10265 else
b619c88e 10266 return Empty;
28ad2460 10267 end if;
b619c88e 10268 end Ancestor_Primitive;
b5360737 10269
b619c88e
AC
10270 -----------------
10271 -- Build_Chain --
10272 -----------------
b5360737 10273
b619c88e
AC
10274 function Build_Chain
10275 (Par_Typ : Entity_Id;
10276 Deriv_Typ : Entity_Id) return Elist_Id
10277 is
10278 Anc_Typ : Entity_Id;
10279 Chain : Elist_Id;
10280 Curr_Typ : Entity_Id;
df3e68b1 10281
b619c88e
AC
10282 begin
10283 Chain := New_Elmt_List;
df3e68b1 10284
b619c88e
AC
10285 -- Add the derived type to the derivation chain
10286
10287 Prepend_Elmt (Deriv_Typ, Chain);
10288
10289 -- Examine all ancestors starting from the derived type climbing
10290 -- towards parent type Par_Typ.
10291
10292 Curr_Typ := Deriv_Typ;
10293 loop
b6e6a4e3
AC
10294 -- Handle the case where the current type is a record which
10295 -- derives from a subtype.
10296
10297 -- subtype Sub_Typ is Par_Typ ...
10298 -- type Deriv_Typ is Sub_Typ ...
10299
10300 if Ekind (Curr_Typ) = E_Record_Type
10301 and then Present (Parent_Subtype (Curr_Typ))
10302 then
10303 Anc_Typ := Parent_Subtype (Curr_Typ);
10304
10305 -- Handle the case where the current type is a record subtype of
10306 -- another subtype.
10307
10308 -- subtype Sub_Typ1 is Par_Typ ...
10309 -- subtype Sub_Typ2 is Sub_Typ1 ...
10310
10311 elsif Ekind (Curr_Typ) = E_Record_Subtype
10312 and then Present (Cloned_Subtype (Curr_Typ))
10313 then
10314 Anc_Typ := Cloned_Subtype (Curr_Typ);
10315
10316 -- Otherwise use the direct parent type
b619c88e 10317
b6e6a4e3
AC
10318 else
10319 Anc_Typ := Etype (Curr_Typ);
10320 end if;
b619c88e 10321
b6e6a4e3 10322 -- Use the first subtype when dealing with itypes
b619c88e
AC
10323
10324 if Is_Itype (Anc_Typ) then
10325 Anc_Typ := First_Subtype (Anc_Typ);
10326 end if;
10327
b6e6a4e3
AC
10328 -- Work with the view which contains the discriminants and stored
10329 -- constraints.
10330
10331 Anc_Typ := Discriminated_View (Anc_Typ);
10332
b619c88e
AC
10333 -- Stop the climb when either the parent type has been reached or
10334 -- there are no more ancestors left to examine.
10335
10336 exit when Anc_Typ = Curr_Typ or else Anc_Typ = Par_Typ;
10337
10338 Prepend_Unique_Elmt (Anc_Typ, Chain);
10339 Curr_Typ := Anc_Typ;
10340 end loop;
10341
10342 return Chain;
10343 end Build_Chain;
10344
10345 ------------------------
10346 -- Discriminated_View --
10347 ------------------------
10348
10349 function Discriminated_View (Typ : Entity_Id) return Entity_Id is
10350 T : Entity_Id;
10351
10352 begin
10353 T := Typ;
10354
10355 -- Use the [underlying] full view when dealing with private types
10356 -- because the view contains all inherited discriminants or stored
10357 -- constraints.
10358
10359 if Is_Private_Type (T) then
10360 if Present (Underlying_Full_View (T)) then
10361 T := Underlying_Full_View (T);
10362
10363 elsif Present (Full_View (T)) then
10364 T := Full_View (T);
10365 end if;
10366 end if;
10367
10368 -- Use the underlying record view when the type is an extenstion of
10369 -- a parent type with unknown discriminants because the view contains
10370 -- all inherited discriminants or stored constraints.
10371
10372 if Ekind (T) = E_Record_Type
10373 and then Present (Underlying_Record_View (T))
10374 then
10375 T := Underlying_Record_View (T);
10376 end if;
10377
10378 return T;
10379 end Discriminated_View;
10380
10381 -----------------------------
10382 -- Find_Discriminant_Value --
10383 -----------------------------
10384
10385 function Find_Discriminant_Value
10386 (Discr : Entity_Id;
10387 Par_Typ : Entity_Id;
10388 Deriv_Typ : Entity_Id;
10389 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id
10390 is
10391 Discr_Pos : constant Uint := Discriminant_Number (Discr);
10392 Typ : constant Entity_Id := Node (Typ_Elmt);
10393
10394 function Find_Constraint_Value
10395 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id;
10396 -- Given constraint Constr, find what it denotes. This is either:
10397 --
10398 -- * An entity which is either a discriminant or a name
10399 --
10400 -- * An expression
10401
10402 ---------------------------
10403 -- Find_Constraint_Value --
10404 ---------------------------
10405
10406 function Find_Constraint_Value
10407 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id
10408 is
10409 begin
10410 if Nkind (Constr) in N_Entity then
10411
10412 -- The constraint denotes a discriminant of the curren type
10413 -- which renames the ancestor discriminant:
10414
10415 -- vv
10416 -- type Typ (D1 : ...; DN : ...) is
10417 -- new Anc (Discr => D1) with ...
10418 -- ^^
10419
10420 if Ekind (Constr) = E_Discriminant then
10421
10422 -- The discriminant belongs to derived type Deriv_Typ. This
10423 -- is the final value for the ancestor discriminant as the
10424 -- derivations chain has been fully exhausted.
10425
10426 if Typ = Deriv_Typ then
10427 return Constr;
10428
10429 -- Otherwise the discriminant may be renamed or constrained
10430 -- at a lower level. Continue looking down the derivation
10431 -- chain.
10432
10433 else
10434 return
10435 Find_Discriminant_Value
10436 (Discr => Constr,
10437 Par_Typ => Par_Typ,
10438 Deriv_Typ => Deriv_Typ,
10439 Typ_Elmt => Next_Elmt (Typ_Elmt));
10440 end if;
10441
10442 -- Otherwise the constraint denotes a reference to some name
10443 -- which results in a Girder discriminant:
10444
10445 -- vvvv
10446 -- Name : ...;
10447 -- type Typ (D1 : ...; DN : ...) is
10448 -- new Anc (Discr => Name) with ...
10449 -- ^^^^
10450
10451 -- Return the name as this is the proper constraint of the
10452 -- discriminant.
10453
10454 else
10455 return Constr;
10456 end if;
10457
10458 -- The constraint denotes a reference to a name
10459
10460 elsif Is_Entity_Name (Constr) then
10461 return Find_Constraint_Value (Entity (Constr));
10462
10463 -- Otherwise the current constraint is an expression which yields
10464 -- a Girder discriminant:
10465
10466 -- type Typ (D1 : ...; DN : ...) is
10467 -- new Anc (Discr => <expression>) with ...
10468 -- ^^^^^^^^^^
10469
10470 -- Return the expression as this is the proper constraint of the
10471 -- discriminant.
10472
10473 else
10474 return Constr;
10475 end if;
10476 end Find_Constraint_Value;
10477
10478 -- Local variables
10479
10480 Constrs : constant Elist_Id := Stored_Constraint (Typ);
10481
10482 Constr_Elmt : Elmt_Id;
10483 Pos : Uint;
10484 Typ_Discr : Entity_Id;
10485
10486 -- Start of processing for Find_Discriminant_Value
10487
10488 begin
10489 -- The algorithm for finding the value of a discriminant works as
10490 -- follows. First, it recreates the derivation chain from Par_Typ
10491 -- to Deriv_Typ as a list:
10492
10493 -- Par_Typ (shown for completeness)
10494 -- v
10495 -- Ancestor_N <-- head of chain
10496 -- v
10497 -- Ancestor_1
10498 -- v
10499 -- Deriv_Typ <-- tail of chain
10500
10501 -- The algorithm then traces the fate of a parent discriminant down
10502 -- the derivation chain. At each derivation level, the discriminant
10503 -- may be either inherited or constrained.
10504
10505 -- 1) Discriminant is inherited: there are two cases, depending on
10506 -- which type is inheriting.
10507
10508 -- 1.1) Deriv_Typ is inheriting:
10509
10510 -- type Ancestor (D_1 : ...) is tagged ...
10511 -- type Deriv_Typ is new Ancestor ...
10512
10513 -- In this case the inherited discriminant is the final value of
10514 -- the parent discriminant because the end of the derivation chain
10515 -- has been reached.
10516
10517 -- 1.2) Some other type is inheriting:
10518
10519 -- type Ancestor_1 (D_1 : ...) is tagged ...
10520 -- type Ancestor_2 is new Ancestor_1 ...
10521
10522 -- In this case the algorithm continues to trace the fate of the
10523 -- inherited discriminant down the derivation chain because it may
10524 -- be further inherited or constrained.
10525
10526 -- 2) Discriminant is constrained: there are three cases, depending
10527 -- on what the constraint is.
10528
10529 -- 2.1) The constraint is another discriminant (aka renaming):
10530
10531 -- type Ancestor_1 (D_1 : ...) is tagged ...
10532 -- type Ancestor_2 (D_2 : ...) is new Ancestor_1 (D_1 => D_2) ...
10533
10534 -- In this case the constraining discriminant becomes the one to
10535 -- track down the derivation chain. The algorithm already knows
10536 -- that D_2 constrains D_1, therefore if the algorithm finds the
10537 -- value of D_2, then this would also be the value for D_1.
10538
10539 -- 2.2) The constraint is a name (aka Girder):
10540
10541 -- Name : ...
10542 -- type Ancestor_1 (D_1 : ...) is tagged ...
10543 -- type Ancestor_2 is new Ancestor_1 (D_1 => Name) ...
10544
10545 -- In this case the name is the final value of D_1 because the
10546 -- discriminant cannot be further constrained.
10547
10548 -- 2.3) The constraint is an expression (aka Girder):
10549
10550 -- type Ancestor_1 (D_1 : ...) is tagged ...
10551 -- type Ancestor_2 is new Ancestor_1 (D_1 => 1 + 2) ...
10552
10553 -- Similar to 2.2, the expression is the final value of D_1
10554
10555 Pos := Uint_1;
10556
10557 -- When a derived type constrains its parent type, all constaints
10558 -- appear in the Stored_Constraint list. Examine the list looking
10559 -- for a positional match.
10560
10561 if Present (Constrs) then
10562 Constr_Elmt := First_Elmt (Constrs);
10563 while Present (Constr_Elmt) loop
10564
10565 -- The position of the current constraint matches that of the
10566 -- ancestor discriminant.
10567
10568 if Pos = Discr_Pos then
10569 return Find_Constraint_Value (Node (Constr_Elmt));
10570 end if;
10571
10572 Next_Elmt (Constr_Elmt);
10573 Pos := Pos + 1;
10574 end loop;
10575
10576 -- Otherwise the derived type does not constraint its parent type in
10577 -- which case it inherits the parent discriminants.
10578
10579 else
10580 Typ_Discr := First_Discriminant (Typ);
10581 while Present (Typ_Discr) loop
10582
10583 -- The position of the current discriminant matches that of the
10584 -- ancestor discriminant.
10585
10586 if Pos = Discr_Pos then
10587 return Find_Constraint_Value (Typ_Discr);
10588 end if;
10589
10590 Next_Discriminant (Typ_Discr);
10591 Pos := Pos + 1;
10592 end loop;
10593 end if;
10594
10595 -- A discriminant must always have a corresponding value. This is
10596 -- either another discriminant, a name, or an expression. If this
10597 -- point is reached, them most likely the derivation chain employs
10598 -- the wrong views of types.
10599
10600 pragma Assert (False);
10601
10602 return Empty;
10603 end Find_Discriminant_Value;
10604
10605 -----------------------
10606 -- Map_Discriminants --
10607 -----------------------
10608
10609 procedure Map_Discriminants
10610 (Par_Typ : Entity_Id;
10611 Deriv_Typ : Entity_Id)
10612 is
10613 Deriv_Chain : constant Elist_Id := Build_Chain (Par_Typ, Deriv_Typ);
10614
10615 Discr : Entity_Id;
10616 Discr_Val : Node_Or_Entity_Id;
10617
10618 begin
10619 -- Examine each discriminant of parent type Par_Typ and find a
10620 -- suitable value for it from the point of view of derived type
10621 -- Deriv_Typ.
10622
10623 if Has_Discriminants (Par_Typ) then
10624 Discr := First_Discriminant (Par_Typ);
10625 while Present (Discr) loop
10626 Discr_Val :=
10627 Find_Discriminant_Value
10628 (Discr => Discr,
10629 Par_Typ => Par_Typ,
10630 Deriv_Typ => Deriv_Typ,
10631 Typ_Elmt => First_Elmt (Deriv_Chain));
10632
10633 -- Create a mapping of the form:
10634
10635 -- parent type discriminant -> value
10636
10637 Type_Map.Set (Discr, Discr_Val);
10638
10639 Next_Discriminant (Discr);
10640 end loop;
10641 end if;
10642 end Map_Discriminants;
10643
10644 --------------------
10645 -- Map_Primitives --
10646 --------------------
10647
10648 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id) is
10649 Deriv_Prim : Entity_Id;
10650 Par_Prim : Entity_Id;
10651 Par_Prims : Elist_Id;
10652 Prim_Elmt : Elmt_Id;
10653
10654 begin
10655 -- Inspect the primitives of the derived type and determine whether
10656 -- they relate to the primitives of the parent type. If there is a
10657 -- meaningful relation, create a mapping of the form:
10658
10659 -- parent type primitive -> perived type primitive
10660
10661 if Present (Direct_Primitive_Operations (Deriv_Typ)) then
10662 Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ));
10663 while Present (Prim_Elmt) loop
10664 Deriv_Prim := Node (Prim_Elmt);
10665
10666 if Is_Subprogram (Deriv_Prim)
10667 and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ
10668 then
10669 Add_Primitive (Deriv_Prim, Par_Typ);
10670 end if;
10671
10672 Next_Elmt (Prim_Elmt);
10673 end loop;
10674 end if;
10675
10676 -- If the parent operation is an interface operation, the overriding
10677 -- indicator is not present. Instead, we get from the interface
10678 -- operation the primitive of the current type that implements it.
10679
10680 if Is_Interface (Par_Typ) then
10681 Par_Prims := Collect_Primitive_Operations (Par_Typ);
10682
10683 if Present (Par_Prims) then
10684 Prim_Elmt := First_Elmt (Par_Prims);
10685
10686 while Present (Prim_Elmt) loop
10687 Par_Prim := Node (Prim_Elmt);
10688 Deriv_Prim :=
10689 Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim);
10690
10691 if Present (Deriv_Prim) then
10692 Type_Map.Set (Par_Prim, Deriv_Prim);
10693 end if;
10694
10695 Next_Elmt (Prim_Elmt);
10696 end loop;
10697 end if;
10698 end if;
10699 end Map_Primitives;
10700
10701 -- Start of processing for Map_Types
10702
10703 begin
10704 -- Nothing to do if there are no types to work with
10705
10706 if No (Parent_Type) or else No (Derived_Type) then
10707 return;
10708
10709 -- Nothing to do if the mapping already exists
10710
10711 elsif Type_Map.Get (Parent_Type) = Derived_Type then
10712 return;
10713
10714 -- Nothing to do if both types are not tagged. Note that untagged types
10715 -- do not have primitive operations and their discriminants are already
10716 -- handled by gigi.
10717
10718 elsif not Is_Tagged_Type (Parent_Type)
10719 or else not Is_Tagged_Type (Derived_Type)
10720 then
10721 return;
10722 end if;
10723
10724 -- Create a mapping of the form
10725
10726 -- parent type -> derived type
10727
10728 -- to prevent any subsequent attempts to produce the same relations
10729
10730 Type_Map.Set (Parent_Type, Derived_Type);
10731
10732 -- Create mappings of the form
10733
10734 -- parent type discriminant -> derived type discriminant
10735 -- <or>
10736 -- parent type discriminant -> constraint
10737
10738 -- Note that mapping of discriminants breaks privacy because it needs to
10739 -- work with those views which contains the discriminants and any stored
10740 -- constraints.
10741
10742 Map_Discriminants
10743 (Par_Typ => Discriminated_View (Parent_Type),
10744 Deriv_Typ => Discriminated_View (Derived_Type));
10745
10746 -- Create mappings of the form
10747
10748 -- parent type primitive -> derived type primitive
10749
10750 Map_Primitives
10751 (Par_Typ => Parent_Type,
10752 Deriv_Typ => Derived_Type);
10753 end Map_Types;
10754
10755 ----------------------------
10756 -- Matching_Standard_Type --
10757 ----------------------------
10758
10759 function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is
10760 pragma Assert (Is_Scalar_Type (Typ));
10761 Siz : constant Uint := Esize (Typ);
10762
10763 begin
10764 -- Floating-point cases
10765
10766 if Is_Floating_Point_Type (Typ) then
10767 if Siz <= Esize (Standard_Short_Float) then
10768 return Standard_Short_Float;
10769 elsif Siz <= Esize (Standard_Float) then
10770 return Standard_Float;
10771 elsif Siz <= Esize (Standard_Long_Float) then
10772 return Standard_Long_Float;
10773 elsif Siz <= Esize (Standard_Long_Long_Float) then
10774 return Standard_Long_Long_Float;
10775 else
10776 raise Program_Error;
10777 end if;
10778
10779 -- Integer cases (includes fixed-point types)
10780
10781 -- Unsigned integer cases (includes normal enumeration types)
10782
b619c88e 10783 else
c7c7dd3a 10784 return Small_Integer_Type_For (Siz, Is_Unsigned_Type (Typ));
b619c88e
AC
10785 end if;
10786 end Matching_Standard_Type;
10787
10788 -----------------------------
10789 -- May_Generate_Large_Temp --
10790 -----------------------------
10791
10792 -- At the current time, the only types that we return False for (i.e. where
10793 -- we decide we know they cannot generate large temps) are ones where we
10794 -- know the size is 256 bits or less at compile time, and we are still not
10795 -- doing a thorough job on arrays and records ???
10796
10797 function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is
10798 begin
10799 if not Size_Known_At_Compile_Time (Typ) then
10800 return False;
10801
10802 elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then
10803 return False;
10804
10805 elsif Is_Array_Type (Typ)
10806 and then Present (Packed_Array_Impl_Type (Typ))
10807 then
10808 return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ));
10809
10810 -- We could do more here to find other small types ???
10811
10812 else
10813 return True;
10814 end if;
10815 end May_Generate_Large_Temp;
10816
341e0bb6
JS
10817 --------------------------------------------
10818 -- Needs_Conditional_Null_Excluding_Check --
10819 --------------------------------------------
10820
10821 function Needs_Conditional_Null_Excluding_Check
10822 (Typ : Entity_Id) return Boolean
10823 is
10824 begin
f537fc00
HK
10825 return
10826 Is_Array_Type (Typ) and then Can_Never_Be_Null (Component_Type (Typ));
341e0bb6
JS
10827 end Needs_Conditional_Null_Excluding_Check;
10828
10829 ----------------------------
10830 -- Needs_Constant_Address --
10831 ----------------------------
10832
10833 function Needs_Constant_Address
10834 (Decl : Node_Id;
10835 Typ : Entity_Id) return Boolean
10836 is
10837 begin
10838 -- If we have no initialization of any kind, then we don't need to place
10839 -- any restrictions on the address clause, because the object will be
10840 -- elaborated after the address clause is evaluated. This happens if the
10841 -- declaration has no initial expression, or the type has no implicit
10842 -- initialization, or the object is imported.
10843
10844 -- The same holds for all initialized scalar types and all access types.
c7c7dd3a
EB
10845 -- Packed bit array types of size up to the maximum integer size are
10846 -- represented using a modular type with an initialization (to zero) and
10847 -- can be processed like other initialized scalar types.
341e0bb6
JS
10848
10849 -- If the type is controlled, code to attach the object to a
10850 -- finalization chain is generated at the point of declaration, and
10851 -- therefore the elaboration of the object cannot be delayed: the
10852 -- address expression must be a constant.
10853
10854 if No (Expression (Decl))
10855 and then not Needs_Finalization (Typ)
10856 and then
10857 (not Has_Non_Null_Base_Init_Proc (Typ)
10858 or else Is_Imported (Defining_Identifier (Decl)))
10859 then
10860 return False;
10861
10862 elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ))
10863 or else Is_Access_Type (Typ)
10864 or else
10865 (Is_Bit_Packed_Array (Typ)
10866 and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ)))
10867 then
10868 return False;
10869
10870 else
341e0bb6
JS
10871 -- Otherwise, we require the address clause to be constant because
10872 -- the call to the initialization procedure (or the attach code) has
10873 -- to happen at the point of the declaration.
10874
10875 -- Actually the IP call has been moved to the freeze actions anyway,
10876 -- so maybe we can relax this restriction???
10877
10878 return True;
10879 end if;
10880 end Needs_Constant_Address;
10881
70482933
RK
10882 ----------------------------
10883 -- New_Class_Wide_Subtype --
10884 ----------------------------
10885
10886 function New_Class_Wide_Subtype
10887 (CW_Typ : Entity_Id;
bebbff91 10888 N : Node_Id) return Entity_Id
70482933 10889 is
fa3717c1
HK
10890 Res : constant Entity_Id := Create_Itype (E_Void, N);
10891
10892 -- Capture relevant attributes of the class-wide subtype which must be
10893 -- restored after the copy.
10894
10895 Res_Chars : constant Name_Id := Chars (Res);
10896 Res_Is_CGE : constant Boolean := Is_Checked_Ghost_Entity (Res);
10897 Res_Is_IGE : constant Boolean := Is_Ignored_Ghost_Entity (Res);
10898 Res_Is_IGN : constant Boolean := Is_Ignored_Ghost_Node (Res);
10899 Res_Scope : constant Entity_Id := Scope (Res);
70482933
RK
10900
10901 begin
10902 Copy_Node (CW_Typ, Res);
fa3717c1
HK
10903
10904 -- Restore the relevant attributes of the class-wide subtype
10905
10906 Set_Chars (Res, Res_Chars);
10907 Set_Is_Checked_Ghost_Entity (Res, Res_Is_CGE);
10908 Set_Is_Ignored_Ghost_Entity (Res, Res_Is_IGE);
10909 Set_Is_Ignored_Ghost_Node (Res, Res_Is_IGN);
10910 Set_Scope (Res, Res_Scope);
10911
10912 -- Decorate the class-wide subtype
10913
70482933 10914 Set_Associated_Node_For_Itype (Res, N);
fa3717c1
HK
10915 Set_Comes_From_Source (Res, False);
10916 Set_Ekind (Res, E_Class_Wide_Subtype);
10917 Set_Etype (Res, Base_Type (CW_Typ));
10918 Set_Freeze_Node (Res, Empty);
10919 Set_Is_Frozen (Res, False);
10920 Set_Is_Itype (Res);
10921 Set_Is_Public (Res, False);
10922 Set_Next_Entity (Res, Empty);
3f6d1daa 10923 Set_Prev_Entity (Res, Empty);
fa3717c1
HK
10924 Set_Sloc (Res, Sloc (N));
10925
70482933 10926 Set_Public_Status (Res);
fa3717c1
HK
10927
10928 return Res;
70482933
RK
10929 end New_Class_Wide_Subtype;
10930
59e54267
ES
10931 -----------------------------------
10932 -- OK_To_Do_Constant_Replacement --
10933 -----------------------------------
10934
10935 function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is
10936 ES : constant Entity_Id := Scope (E);
10937 CS : Entity_Id;
10938
10939 begin
10940 -- Do not replace statically allocated objects, because they may be
10941 -- modified outside the current scope.
10942
10943 if Is_Statically_Allocated (E) then
10944 return False;
10945
10946 -- Do not replace aliased or volatile objects, since we don't know what
10947 -- else might change the value.
10948
10949 elsif Is_Aliased (E) or else Treat_As_Volatile (E) then
10950 return False;
10951
10952 -- Debug flag -gnatdM disconnects this optimization
10953
10954 elsif Debug_Flag_MM then
10955 return False;
10956
10957 -- Otherwise check scopes
10958
10959 else
59e54267
ES
10960 CS := Current_Scope;
10961
10962 loop
10963 -- If we are in right scope, replacement is safe
10964
10965 if CS = ES then
10966 return True;
10967
10968 -- Packages do not affect the determination of safety
10969
10970 elsif Ekind (CS) = E_Package then
59e54267 10971 exit when CS = Standard_Standard;
05350ac6 10972 CS := Scope (CS);
59e54267
ES
10973
10974 -- Blocks do not affect the determination of safety
10975
10976 elsif Ekind (CS) = E_Block then
10977 CS := Scope (CS);
10978
05350ac6
BD
10979 -- Loops do not affect the determination of safety. Note that we
10980 -- kill all current values on entry to a loop, so we are just
10981 -- talking about processing within a loop here.
10982
10983 elsif Ekind (CS) = E_Loop then
10984 CS := Scope (CS);
10985
59e54267
ES
10986 -- Otherwise, the reference is dubious, and we cannot be sure that
10987 -- it is safe to do the replacement.
10988
10989 else
10990 exit;
10991 end if;
10992 end loop;
10993
10994 return False;
10995 end if;
10996 end OK_To_Do_Constant_Replacement;
10997
0712790c
ES
10998 ------------------------------------
10999 -- Possible_Bit_Aligned_Component --
11000 ------------------------------------
11001
11002 function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
11003 begin
184a23e9
HK
11004 -- Do not process an unanalyzed node because it is not yet decorated and
11005 -- most checks performed below will fail.
11006
11007 if not Analyzed (N) then
11008 return False;
11009 end if;
11010
f167c735
AC
11011 -- There are never alignment issues in CodePeer mode
11012
11013 if CodePeer_Mode then
11014 return False;
11015 end if;
11016
0712790c
ES
11017 case Nkind (N) is
11018
11019 -- Case of indexed component
11020
11021 when N_Indexed_Component =>
11022 declare
11023 P : constant Node_Id := Prefix (N);
11024 Ptyp : constant Entity_Id := Etype (P);
11025
11026 begin
c7c7dd3a
EB
11027 -- If we know the component size and it is not larger than the
11028 -- maximum integer size, then we are OK. The back end does the
11029 -- assignment of small misaligned objects correctly.
0712790c
ES
11030
11031 if Known_Static_Component_Size (Ptyp)
c7c7dd3a 11032 and then Component_Size (Ptyp) <= System_Max_Integer_Size
0712790c
ES
11033 then
11034 return False;
11035
11036 -- Otherwise, we need to test the prefix, to see if we are
11037 -- indexing from a possibly unaligned component.
11038
11039 else
11040 return Possible_Bit_Aligned_Component (P);
11041 end if;
11042 end;
11043
11044 -- Case of selected component
11045
11046 when N_Selected_Component =>
11047 declare
11048 P : constant Node_Id := Prefix (N);
11049 Comp : constant Entity_Id := Entity (Selector_Name (N));
11050
11051 begin
fba9fcae
EB
11052 -- This is the crucial test: if the component itself causes
11053 -- trouble, then we can stop and return True.
0712790c
ES
11054
11055 if Component_May_Be_Bit_Aligned (Comp) then
11056 return True;
fba9fcae
EB
11057
11058 -- Otherwise, we need to test the prefix, to see if we are
11059 -- selecting from a possibly unaligned component.
11060
0712790c
ES
11061 else
11062 return Possible_Bit_Aligned_Component (P);
11063 end if;
11064 end;
11065
65df5b71 11066 -- For a slice, test the prefix, if that is possibly misaligned,
a90bd866 11067 -- then for sure the slice is.
65df5b71
HK
11068
11069 when N_Slice =>
11070 return Possible_Bit_Aligned_Component (Prefix (N));
11071
83de674b 11072 -- For an unchecked conversion, check whether the expression may
fba9fcae 11073 -- be bit aligned.
83de674b
AC
11074
11075 when N_Unchecked_Type_Conversion =>
11076 return Possible_Bit_Aligned_Component (Expression (N));
11077
65df5b71
HK
11078 -- If we have none of the above, it means that we have fallen off the
11079 -- top testing prefixes recursively, and we now have a stand alone
469fba4a
AC
11080 -- object, where we don't have a problem, unless this is a renaming,
11081 -- in which case we need to look into the renamed object.
0712790c
ES
11082
11083 when others =>
469fba4a
AC
11084 if Is_Entity_Name (N)
11085 and then Present (Renamed_Object (Entity (N)))
11086 then
11087 return
11088 Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
11089 else
11090 return False;
11091 end if;
0712790c
ES
11092 end case;
11093 end Possible_Bit_Aligned_Component;
11094
2ba7e31e
AC
11095 -----------------------------------------------
11096 -- Process_Statements_For_Controlled_Objects --
11097 -----------------------------------------------
11098
11099 procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is
11100 Loc : constant Source_Ptr := Sloc (N);
11101
11102 function Are_Wrapped (L : List_Id) return Boolean;
11103 -- Determine whether list L contains only one statement which is a block
11104
7edfb4c6
HK
11105 function Wrap_Statements_In_Block
11106 (L : List_Id;
11107 Scop : Entity_Id := Current_Scope) return Node_Id;
2ba7e31e 11108 -- Given a list of statements L, wrap it in a block statement and return
7edfb4c6
HK
11109 -- the generated node. Scop is either the current scope or the scope of
11110 -- the context (if applicable).
2ba7e31e
AC
11111
11112 -----------------
11113 -- Are_Wrapped --
11114 -----------------
11115
11116 function Are_Wrapped (L : List_Id) return Boolean is
11117 Stmt : constant Node_Id := First (L);
2ba7e31e
AC
11118 begin
11119 return
11120 Present (Stmt)
11121 and then No (Next (Stmt))
11122 and then Nkind (Stmt) = N_Block_Statement;
11123 end Are_Wrapped;
11124
11125 ------------------------------
11126 -- Wrap_Statements_In_Block --
11127 ------------------------------
11128
7edfb4c6
HK
11129 function Wrap_Statements_In_Block
11130 (L : List_Id;
11131 Scop : Entity_Id := Current_Scope) return Node_Id
11132 is
11133 Block_Id : Entity_Id;
11134 Block_Nod : Node_Id;
11135 Iter_Loop : Entity_Id;
11136
2ba7e31e 11137 begin
7edfb4c6 11138 Block_Nod :=
2ba7e31e 11139 Make_Block_Statement (Loc,
7edfb4c6 11140 Declarations => No_List,
2ba7e31e
AC
11141 Handled_Statement_Sequence =>
11142 Make_Handled_Sequence_Of_Statements (Loc,
11143 Statements => L));
7edfb4c6
HK
11144
11145 -- Create a label for the block in case the block needs to manage the
11146 -- secondary stack. A label allows for flag Uses_Sec_Stack to be set.
11147
11148 Add_Block_Identifier (Block_Nod, Block_Id);
11149
11150 -- When wrapping the statements of an iterator loop, check whether
11151 -- the loop requires secondary stack management and if so, propagate
3b8481cb 11152 -- the appropriate flags to the block. This ensures that the cursor
c624298a 11153 -- is properly cleaned up at each iteration of the loop.
7edfb4c6
HK
11154
11155 Iter_Loop := Find_Enclosing_Iterator_Loop (Scop);
11156
3b8481cb 11157 if Present (Iter_Loop) then
c624298a
AC
11158 Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop));
11159
11160 -- Secondary stack reclamation is suppressed when the associated
11161 -- iterator loop contains a return statement which uses the stack.
11162
3b8481cb
AC
11163 Set_Sec_Stack_Needed_For_Return
11164 (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop));
7edfb4c6
HK
11165 end if;
11166
11167 return Block_Nod;
2ba7e31e
AC
11168 end Wrap_Statements_In_Block;
11169
25b589cb
AC
11170 -- Local variables
11171
11172 Block : Node_Id;
11173
2ba7e31e
AC
11174 -- Start of processing for Process_Statements_For_Controlled_Objects
11175
11176 begin
25b589cb
AC
11177 -- Whenever a non-handled statement list is wrapped in a block, the
11178 -- block must be explicitly analyzed to redecorate all entities in the
11179 -- list and ensure that a finalizer is properly built.
11180
2ba7e31e 11181 case Nkind (N) is
d8f43ee6
HK
11182 when N_Conditional_Entry_Call
11183 | N_Elsif_Part
11184 | N_If_Statement
11185 | N_Selective_Accept
11186 =>
2ba7e31e
AC
11187 -- Check the "then statements" for elsif parts and if statements
11188
4a08c95c 11189 if Nkind (N) in N_Elsif_Part | N_If_Statement
2ba7e31e
AC
11190 and then not Is_Empty_List (Then_Statements (N))
11191 and then not Are_Wrapped (Then_Statements (N))
11192 and then Requires_Cleanup_Actions
c581c520
PMR
11193 (L => Then_Statements (N),
11194 Lib_Level => False,
40c21e91 11195 Nested_Constructs => False)
2ba7e31e 11196 then
25b589cb
AC
11197 Block := Wrap_Statements_In_Block (Then_Statements (N));
11198 Set_Then_Statements (N, New_List (Block));
11199
11200 Analyze (Block);
2ba7e31e
AC
11201 end if;
11202
11203 -- Check the "else statements" for conditional entry calls, if
11204 -- statements and selective accepts.
11205
4a08c95c
AC
11206 if Nkind (N) in
11207 N_Conditional_Entry_Call | N_If_Statement | N_Selective_Accept
2ba7e31e
AC
11208 and then not Is_Empty_List (Else_Statements (N))
11209 and then not Are_Wrapped (Else_Statements (N))
11210 and then Requires_Cleanup_Actions
c581c520
PMR
11211 (L => Else_Statements (N),
11212 Lib_Level => False,
40c21e91 11213 Nested_Constructs => False)
2ba7e31e 11214 then
25b589cb
AC
11215 Block := Wrap_Statements_In_Block (Else_Statements (N));
11216 Set_Else_Statements (N, New_List (Block));
11217
11218 Analyze (Block);
2ba7e31e
AC
11219 end if;
11220
d8f43ee6
HK
11221 when N_Abortable_Part
11222 | N_Accept_Alternative
11223 | N_Case_Statement_Alternative
11224 | N_Delay_Alternative
11225 | N_Entry_Call_Alternative
11226 | N_Exception_Handler
11227 | N_Loop_Statement
11228 | N_Triggering_Alternative
11229 =>
2ba7e31e
AC
11230 if not Is_Empty_List (Statements (N))
11231 and then not Are_Wrapped (Statements (N))
40c21e91 11232 and then Requires_Cleanup_Actions
c581c520
PMR
11233 (L => Statements (N),
11234 Lib_Level => False,
40c21e91 11235 Nested_Constructs => False)
2ba7e31e 11236 then
7edfb4c6
HK
11237 if Nkind (N) = N_Loop_Statement
11238 and then Present (Identifier (N))
11239 then
11240 Block :=
11241 Wrap_Statements_In_Block
11242 (L => Statements (N),
11243 Scop => Entity (Identifier (N)));
11244 else
11245 Block := Wrap_Statements_In_Block (Statements (N));
11246 end if;
25b589cb 11247
7edfb4c6 11248 Set_Statements (N, New_List (Block));
25b589cb 11249 Analyze (Block);
2ba7e31e
AC
11250 end if;
11251
fb9dd1c7
PMR
11252 -- Could be e.g. a loop that was transformed into a block or null
11253 -- statement. Do nothing for terminate alternatives.
11254
e201023c
PMR
11255 when N_Block_Statement
11256 | N_Null_Statement
11257 | N_Terminate_Alternative
11258 =>
2ba7e31e 11259 null;
fb9dd1c7
PMR
11260
11261 when others =>
11262 raise Program_Error;
2ba7e31e
AC
11263 end case;
11264 end Process_Statements_For_Controlled_Objects;
11265
2c9f8c0a
AC
11266 ------------------
11267 -- Power_Of_Two --
11268 ------------------
11269
11270 function Power_Of_Two (N : Node_Id) return Nat is
11271 Typ : constant Entity_Id := Etype (N);
11272 pragma Assert (Is_Integer_Type (Typ));
02bb0765 11273
2c9f8c0a
AC
11274 Siz : constant Nat := UI_To_Int (Esize (Typ));
11275 Val : Uint;
11276
11277 begin
11278 if not Compile_Time_Known_Value (N) then
11279 return 0;
11280
11281 else
11282 Val := Expr_Value (N);
11283 for J in 1 .. Siz - 1 loop
11284 if Val = Uint_2 ** J then
11285 return J;
11286 end if;
11287 end loop;
11288
11289 return 0;
11290 end if;
11291 end Power_Of_Two;
11292
3a3af4c3
AC
11293 ----------------------
11294 -- Remove_Init_Call --
11295 ----------------------
11296
11297 function Remove_Init_Call
11298 (Var : Entity_Id;
11299 Rep_Clause : Node_Id) return Node_Id
11300 is
11301 Par : constant Node_Id := Parent (Var);
11302 Typ : constant Entity_Id := Etype (Var);
11303
11304 Init_Proc : Entity_Id;
11305 -- Initialization procedure for Typ
11306
11307 function Find_Init_Call_In_List (From : Node_Id) return Node_Id;
11308 -- Look for init call for Var starting at From and scanning the
11309 -- enclosing list until Rep_Clause or the end of the list is reached.
11310
11311 ----------------------------
11312 -- Find_Init_Call_In_List --
11313 ----------------------------
11314
11315 function Find_Init_Call_In_List (From : Node_Id) return Node_Id is
11316 Init_Call : Node_Id;
ae05cdd6 11317
3a3af4c3
AC
11318 begin
11319 Init_Call := From;
3a3af4c3
AC
11320 while Present (Init_Call) and then Init_Call /= Rep_Clause loop
11321 if Nkind (Init_Call) = N_Procedure_Call_Statement
11322 and then Is_Entity_Name (Name (Init_Call))
11323 and then Entity (Name (Init_Call)) = Init_Proc
11324 then
11325 return Init_Call;
11326 end if;
11327
11328 Next (Init_Call);
11329 end loop;
11330
11331 return Empty;
11332 end Find_Init_Call_In_List;
11333
11334 Init_Call : Node_Id;
11335
afab03da 11336 -- Start of processing for Remove_Init_Call
3a3af4c3
AC
11337
11338 begin
11339 if Present (Initialization_Statements (Var)) then
11340 Init_Call := Initialization_Statements (Var);
11341 Set_Initialization_Statements (Var, Empty);
11342
11343 elsif not Has_Non_Null_Base_Init_Proc (Typ) then
11344
11345 -- No init proc for the type, so obviously no call to be found
11346
11347 return Empty;
11348
11349 else
11350 -- We might be able to handle other cases below by just properly
11351 -- setting Initialization_Statements at the point where the init proc
11352 -- call is generated???
11353
11354 Init_Proc := Base_Init_Proc (Typ);
11355
11356 -- First scan the list containing the declaration of Var
11357
11358 Init_Call := Find_Init_Call_In_List (From => Next (Par));
11359
11360 -- If not found, also look on Var's freeze actions list, if any,
11361 -- since the init call may have been moved there (case of an address
11362 -- clause applying to Var).
11363
11364 if No (Init_Call) and then Present (Freeze_Node (Var)) then
11365 Init_Call :=
11366 Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
11367 end if;
11368
11369 -- If the initialization call has actuals that use the secondary
11370 -- stack, the call may have been wrapped into a temporary block, in
11371 -- which case the block itself has to be removed.
11372
11373 if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
11374 declare
11375 Blk : constant Node_Id := Next (Par);
11376 begin
11377 if Present
11378 (Find_Init_Call_In_List
11379 (First (Statements (Handled_Statement_Sequence (Blk)))))
11380 then
11381 Init_Call := Blk;
11382 end if;
11383 end;
11384 end if;
11385 end if;
11386
11387 if Present (Init_Call) then
4b0ba356
ES
11388 -- If restrictions have forbidden Aborts, the initialization call
11389 -- for objects that require deep initialization has not been wrapped
11390 -- into the following block (see Exp_Ch3, Default_Initialize_Object)
11391 -- so if present remove it as well, and include the IP call in it,
11392 -- in the rare case the caller may need to simply displace the
11393 -- initialization, as is done for a later address specification.
11394
11395 if Nkind (Next (Init_Call)) = N_Block_Statement
11396 and then Is_Initialization_Block (Next (Init_Call))
11397 then
11398 declare
11399 IP_Call : constant Node_Id := Init_Call;
11400 begin
11401 Init_Call := Next (IP_Call);
11402 Remove (IP_Call);
11403 Prepend (IP_Call,
11404 Statements (Handled_Statement_Sequence (Init_Call)));
11405 end;
11406 end if;
11407
3a3af4c3
AC
11408 Remove (Init_Call);
11409 end if;
afab03da 11410
3a3af4c3
AC
11411 return Init_Call;
11412 end Remove_Init_Call;
11413
70482933
RK
11414 -------------------------
11415 -- Remove_Side_Effects --
11416 -------------------------
11417
11418 procedure Remove_Side_Effects
89d3b1a1
AC
11419 (Exp : Node_Id;
11420 Name_Req : Boolean := False;
11421 Renaming_Req : Boolean := False;
11422 Variable_Ref : Boolean := False;
11423 Related_Id : Entity_Id := Empty;
11424 Is_Low_Bound : Boolean := False;
11425 Is_High_Bound : Boolean := False;
11426 Check_Side_Effects : Boolean := True)
70482933 11427 is
2934b84a
AC
11428 function Build_Temporary
11429 (Loc : Source_Ptr;
11430 Id : Character;
11431 Related_Nod : Node_Id := Empty) return Entity_Id;
09edc2c2
AC
11432 -- Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod
11433 -- is present (xxx is taken from the Chars field of Related_Nod),
8f8f531f
PMR
11434 -- otherwise it generates an internal temporary. The created temporary
11435 -- entity is marked as internal.
2934b84a 11436
a6fecb06 11437 function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean;
595c9aeb 11438 -- Computes whether a side effect is possible in SPARK, which should
a6fecb06 11439 -- be handled by removing it from the expression for GNATprove. Note
595c9aeb 11440 -- that other side effects related to volatile variables are handled
a6fecb06
YM
11441 -- separately.
11442
2934b84a
AC
11443 ---------------------
11444 -- Build_Temporary --
11445 ---------------------
11446
11447 function Build_Temporary
11448 (Loc : Source_Ptr;
11449 Id : Character;
11450 Related_Nod : Node_Id := Empty) return Entity_Id
11451 is
8f8f531f 11452 Temp_Id : Entity_Id;
8ce62196 11453 Temp_Nam : Name_Id;
2934b84a
AC
11454
11455 begin
11456 -- The context requires an external symbol
11457
11458 if Present (Related_Id) then
11459 if Is_Low_Bound then
11460 Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST");
11461 else pragma Assert (Is_High_Bound);
11462 Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST");
11463 end if;
11464
8f8f531f 11465 Temp_Id := Make_Defining_Identifier (Loc, Temp_Nam);
2934b84a
AC
11466
11467 -- Otherwise generate an internal temporary
11468
11469 else
8f8f531f 11470 Temp_Id := Make_Temporary (Loc, Id, Related_Nod);
2934b84a 11471 end if;
8f8f531f
PMR
11472
11473 Set_Is_Internal (Temp_Id);
11474
11475 return Temp_Id;
2934b84a
AC
11476 end Build_Temporary;
11477
a6fecb06
YM
11478 -----------------------------------
11479 -- Possible_Side_Effect_In_SPARK --
11480 -----------------------------------
11481
11482 function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean is
11483 begin
11484 -- Side-effect removal in SPARK should only occur when not inside a
11485 -- generic and not doing a preanalysis, inside an object renaming or
11486 -- a type declaration or a for-loop iteration scheme.
11487
11488 return not Inside_A_Generic
11489 and then Full_Analysis
11490 and then Nkind (Enclosing_Declaration (Exp)) in
11491 N_Full_Type_Declaration
11492 | N_Iterator_Specification
11493 | N_Loop_Parameter_Specification
11494 | N_Object_Renaming_Declaration
11495 | N_Subtype_Declaration;
11496 end Possible_Side_Effect_In_SPARK;
11497
2934b84a
AC
11498 -- Local variables
11499
3217f71e
AC
11500 Loc : constant Source_Ptr := Sloc (Exp);
11501 Exp_Type : constant Entity_Id := Etype (Exp);
11502 Svg_Suppress : constant Suppress_Record := Scope_Suppress;
70482933 11503 Def_Id : Entity_Id;
cc570be6
AC
11504 E : Node_Id;
11505 New_Exp : Node_Id;
11506 Ptr_Typ_Decl : Node_Id;
70482933
RK
11507 Ref_Type : Entity_Id;
11508 Res : Node_Id;
70482933 11509
2934b84a
AC
11510 -- Start of processing for Remove_Side_Effects
11511
70482933 11512 begin
f5da7a97
YM
11513 -- Handle cases in which there is nothing to do. In GNATprove mode,
11514 -- removal of side effects is useful for the light expansion of
a6fecb06 11515 -- renamings.
c269a1f5 11516
a6ce7e76 11517 if not Expander_Active
a6fecb06
YM
11518 and then not
11519 (GNATprove_Mode and then Possible_Side_Effect_In_SPARK (Exp))
a6ce7e76 11520 then
cae81f17
JM
11521 return;
11522
11523 -- Cannot generate temporaries if the invocation to remove side effects
11524 -- was issued too early and the type of the expression is not resolved
11525 -- (this happens because routines Duplicate_Subexpr_XX implicitly invoke
11526 -- Remove_Side_Effects).
11527
10edebe7
AC
11528 elsif No (Exp_Type)
11529 or else Ekind (Exp_Type) = E_Access_Attribute_Type
11530 then
11531 return;
11532
11533 -- Nothing to do if prior expansion determined that a function call does
11534 -- not require side effect removal.
11535
11536 elsif Nkind (Exp) = N_Function_Call
11537 and then No_Side_Effect_Removal (Exp)
11538 then
cae81f17
JM
11539 return;
11540
11541 -- No action needed for side-effect free expressions
70482933 11542
89d3b1a1
AC
11543 elsif Check_Side_Effects
11544 and then Side_Effect_Free (Exp, Name_Req, Variable_Ref)
11545 then
70482933 11546 return;
78cac738
JM
11547
11548 -- Generating C code we cannot remove side effect of function returning
11549 -- class-wide types since there is no secondary stack (required to use
11550 -- 'reference).
11551
11552 elsif Modify_Tree_For_C
11553 and then Nkind (Exp) = N_Function_Call
11554 and then Is_Class_Wide_Type (Etype (Exp))
11555 then
11556 return;
70482933
RK
11557 end if;
11558
22e89283 11559 -- The remaining processing is done with all checks suppressed
67b8ac46
AC
11560
11561 -- Note: from now on, don't use return statements, instead do a goto
11562 -- Leave, to ensure that we properly restore Scope_Suppress.Suppress.
70482933 11563
a7f1b24f 11564 Scope_Suppress.Suppress := (others => True);
70482933 11565
cf9e3829
EB
11566 -- If this is a side-effect free attribute reference whose expressions
11567 -- are also side-effect free and whose prefix is not a name, remove the
11568 -- side effects of the prefix. A copy of the prefix is required in this
11569 -- case and it is better not to make an additional one for the attribute
11570 -- itself, because the return type of many of them is universal integer,
11571 -- which is a very large type for a temporary.
11572
11573 if Nkind (Exp) = N_Attribute_Reference
11574 and then Side_Effect_Free_Attribute (Attribute_Name (Exp))
11575 and then Side_Effect_Free (Expressions (Exp), Name_Req, Variable_Ref)
11576 and then not Is_Name_Reference (Prefix (Exp))
11577 then
11578 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
11579 goto Leave;
11580
67cc7a30 11581 -- If this is an elementary or a small not-by-reference record type, and
34da9c98
EB
11582 -- we need to capture the value, just make a constant; this is cheap and
11583 -- objects of both kinds of types can be bit aligned, so it might not be
11584 -- possible to generate a reference to them. Likewise if this is not a
67cc7a30 11585 -- name reference, except for a type conversion, because we would enter
34da9c98
EB
11586 -- an infinite recursion with Checks.Apply_Predicate_Check if the target
11587 -- type has predicates (and type conversions need a specific treatment
11588 -- anyway, see below). Also do it if we have a volatile reference and
11589 -- Name_Req is not set (see comments for Side_Effect_Free).
11590
cf9e3829
EB
11591 elsif (Is_Elementary_Type (Exp_Type)
11592 or else (Is_Record_Type (Exp_Type)
11593 and then Known_Static_RM_Size (Exp_Type)
c7c7dd3a 11594 and then RM_Size (Exp_Type) <= System_Max_Integer_Size
cf9e3829
EB
11595 and then not Has_Discriminants (Exp_Type)
11596 and then not Is_By_Reference_Type (Exp_Type)))
d9e0a587 11597 and then (Variable_Ref
22e89283
AC
11598 or else (not Is_Name_Reference (Exp)
11599 and then Nkind (Exp) /= N_Type_Conversion)
365c8496
RD
11600 or else (not Name_Req
11601 and then Is_Volatile_Reference (Exp)))
d9e0a587 11602 then
2934b84a 11603 Def_Id := Build_Temporary (Loc, 'R', Exp);
d9e0a587 11604 Set_Etype (Def_Id, Exp_Type);
e4494292 11605 Res := New_Occurrence_Of (Def_Id, Loc);
d9e0a587 11606
273adcdf
AC
11607 -- If the expression is a packed reference, it must be reanalyzed and
11608 -- expanded, depending on context. This is the case for actuals where
11609 -- a constraint check may capture the actual before expansion of the
11610 -- call is complete.
8cce3d75
AC
11611
11612 if Nkind (Exp) = N_Indexed_Component
11613 and then Is_Packed (Etype (Prefix (Exp)))
11614 then
11615 Set_Analyzed (Exp, False);
11616 Set_Analyzed (Prefix (Exp), False);
11617 end if;
11618
a43f6434
AC
11619 -- Generate:
11620 -- Rnn : Exp_Type renames Expr;
11621
e9427de1
YM
11622 -- In GNATprove mode, we prefer to use renamings for intermediate
11623 -- variables to definition of constants, due to the implicit move
11624 -- operation that such a constant definition causes as part of the
3f833dc2
GD
11625 -- support in GNATprove for ownership pointers. Hence, we generate
11626 -- a renaming for a reference to an object of a nonscalar type.
e9427de1
YM
11627
11628 if Renaming_Req
11629 or else (GNATprove_Mode
11630 and then Is_Object_Reference (Exp)
11631 and then not Is_Scalar_Type (Exp_Type))
11632 then
a43f6434
AC
11633 E :=
11634 Make_Object_Renaming_Declaration (Loc,
11635 Defining_Identifier => Def_Id,
11636 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
11637 Name => Relocate_Node (Exp));
11638
11639 -- Generate:
11640 -- Rnn : constant Exp_Type := Expr;
11641
11642 else
11643 E :=
11644 Make_Object_Declaration (Loc,
11645 Defining_Identifier => Def_Id,
11646 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
11647 Constant_Present => True,
11648 Expression => Relocate_Node (Exp));
11649
11650 Set_Assignment_OK (E);
11651 end if;
d9e0a587 11652
d9e0a587
EB
11653 Insert_Action (Exp, E);
11654
273adcdf 11655 -- If the expression has the form v.all then we can just capture the
bb012790
AC
11656 -- pointer, and then do an explicit dereference on the result, but
11657 -- this is not right if this is a volatile reference.
70482933 11658
bb012790
AC
11659 elsif Nkind (Exp) = N_Explicit_Dereference
11660 and then not Is_Volatile_Reference (Exp)
11661 then
2934b84a 11662 Def_Id := Build_Temporary (Loc, 'R', Exp);
70482933 11663 Res :=
e4494292 11664 Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc));
70482933
RK
11665
11666 Insert_Action (Exp,
11667 Make_Object_Declaration (Loc,
11668 Defining_Identifier => Def_Id,
11669 Object_Definition =>
e4494292 11670 New_Occurrence_Of (Etype (Prefix (Exp)), Loc),
70482933
RK
11671 Constant_Present => True,
11672 Expression => Relocate_Node (Prefix (Exp))));
11673
273adcdf
AC
11674 -- Similar processing for an unchecked conversion of an expression of
11675 -- the form v.all, where we want the same kind of treatment.
fbf5a39b
AC
11676
11677 elsif Nkind (Exp) = N_Unchecked_Type_Conversion
11678 and then Nkind (Expression (Exp)) = N_Explicit_Dereference
11679 then
8adcacef 11680 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
67b8ac46 11681 goto Leave;
fbf5a39b 11682
70482933 11683 -- If this is a type conversion, leave the type conversion and remove
e4542648
EB
11684 -- side effects in the expression, unless it is of universal integer,
11685 -- which is a very large type for a temporary. This is important in
11686 -- several circumstances: for change of representations and also when
11687 -- this is a view conversion to a smaller object, where gigi can end
11688 -- up creating its own temporary of the wrong size.
11689
11690 elsif Nkind (Exp) = N_Type_Conversion
11691 and then Etype (Expression (Exp)) /= Universal_Integer
11692 then
8adcacef 11693 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref);
6905a049
AC
11694
11695 -- Generating C code the type conversion of an access to constrained
11696 -- array type into an access to unconstrained array type involves
11697 -- initializing a fat pointer and the expression must be free of
11698 -- side effects to safely compute its bounds.
11699
c63a2ad6 11700 if Modify_Tree_For_C
6905a049
AC
11701 and then Is_Access_Type (Etype (Exp))
11702 and then Is_Array_Type (Designated_Type (Etype (Exp)))
11703 and then not Is_Constrained (Designated_Type (Etype (Exp)))
11704 then
11705 Def_Id := Build_Temporary (Loc, 'R', Exp);
11706 Set_Etype (Def_Id, Exp_Type);
11707 Res := New_Occurrence_Of (Def_Id, Loc);
11708
11709 Insert_Action (Exp,
11710 Make_Object_Declaration (Loc,
11711 Defining_Identifier => Def_Id,
11712 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
11713 Constant_Present => True,
11714 Expression => Relocate_Node (Exp)));
11715 else
11716 goto Leave;
11717 end if;
70482933 11718
d9e0a587
EB
11719 -- If this is an unchecked conversion that Gigi can't handle, make
11720 -- a copy or a use a renaming to capture the value.
11721
11722 elsif Nkind (Exp) = N_Unchecked_Type_Conversion
11723 and then not Safe_Unchecked_Type_Conversion (Exp)
11724 then
048e5cef 11725 if CW_Or_Has_Controlled_Part (Exp_Type) then
d9e0a587
EB
11726
11727 -- Use a renaming to capture the expression, rather than create
11728 -- a controlled temporary.
11729
2934b84a
AC
11730 Def_Id := Build_Temporary (Loc, 'R', Exp);
11731 Res := New_Occurrence_Of (Def_Id, Loc);
d9e0a587
EB
11732
11733 Insert_Action (Exp,
11734 Make_Object_Renaming_Declaration (Loc,
11735 Defining_Identifier => Def_Id,
e4494292 11736 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
d9e0a587
EB
11737 Name => Relocate_Node (Exp)));
11738
11739 else
2934b84a 11740 Def_Id := Build_Temporary (Loc, 'R', Exp);
d9e0a587 11741 Set_Etype (Def_Id, Exp_Type);
2934b84a 11742 Res := New_Occurrence_Of (Def_Id, Loc);
d9e0a587
EB
11743
11744 E :=
11745 Make_Object_Declaration (Loc,
11746 Defining_Identifier => Def_Id,
e4494292 11747 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
d9e0a587
EB
11748 Constant_Present => not Is_Variable (Exp),
11749 Expression => Relocate_Node (Exp));
11750
11751 Set_Assignment_OK (E);
11752 Insert_Action (Exp, E);
11753 end if;
11754
1b93e420
EB
11755 -- If this is a packed array component or a selected component with a
11756 -- nonstandard representation, we cannot generate a reference because
11757 -- the component may be unaligned, so we must use a renaming and this
a36a2913
EB
11758 -- renaming is handled by the front end, as the back end may balk at
11759 -- the nonstandard representation (see Evaluation_Required in Exp_Ch8).
1b93e420
EB
11760
11761 elsif Nkind (Exp) in N_Indexed_Component | N_Selected_Component
11762 and then Has_Non_Standard_Rep (Etype (Prefix (Exp)))
11763 then
11764 Def_Id := Build_Temporary (Loc, 'R', Exp);
11765 Res := New_Occurrence_Of (Def_Id, Loc);
11766
11767 Insert_Action (Exp,
11768 Make_Object_Renaming_Declaration (Loc,
11769 Defining_Identifier => Def_Id,
11770 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
11771 Name => Relocate_Node (Exp)));
11772
a36a2913 11773 -- For an expression that denotes a name, we can use a renaming scheme.
18a2ad5d 11774 -- This is needed for correctness in the case of a volatile object of
3f833dc2 11775 -- a nonvolatile type because the Make_Reference call of the "default"
273adcdf 11776 -- approach would generate an illegal access value (an access value
bb012790 11777 -- cannot designate such an object - see Analyze_Reference).
18a2ad5d 11778
22e89283 11779 elsif Is_Name_Reference (Exp)
bb012790
AC
11780
11781 -- We skip using this scheme if we have an object of a volatile
11782 -- type and we do not have Name_Req set true (see comments for
11783 -- Side_Effect_Free).
11784
676e8420 11785 and then (Name_Req or else not Treat_As_Volatile (Exp_Type))
70482933 11786 then
2934b84a 11787 Def_Id := Build_Temporary (Loc, 'R', Exp);
22e89283 11788 Res := New_Occurrence_Of (Def_Id, Loc);
70482933 11789
22e89283
AC
11790 Insert_Action (Exp,
11791 Make_Object_Renaming_Declaration (Loc,
11792 Defining_Identifier => Def_Id,
11793 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc),
11794 Name => Relocate_Node (Exp)));
70482933 11795
22e89283
AC
11796 -- Avoid generating a variable-sized temporary, by generating the
11797 -- reference just for the function call. The transformation could be
11798 -- refined to apply only when the array component is constrained by a
11799 -- discriminant???
11800
11801 elsif Nkind (Exp) = N_Selected_Component
11802 and then Nkind (Prefix (Exp)) = N_Function_Call
11803 and then Is_Array_Type (Exp_Type)
11804 then
11805 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref);
11806 goto Leave;
11807
11808 -- Otherwise we generate a reference to the expression
70482933
RK
11809
11810 else
c7518e6f
AC
11811 -- When generating C code we cannot consider side effect free object
11812 -- declarations that have discriminants and are initialized by means
11813 -- of a function call since on this target there is no secondary
11814 -- stack to store the return value and the expander may generate an
11815 -- extra call to the function to compute the discriminant value. In
11816 -- addition, for targets that have secondary stack, the expansion of
11817 -- functions with side effects involves the generation of an access
11818 -- type to capture the return value stored in the secondary stack;
11819 -- by contrast when generating C code such expansion generates an
11820 -- internal object declaration (no access type involved) which must
11821 -- be identified here to avoid entering into a never-ending loop
11822 -- generating internal object declarations.
11823
d43123ee 11824 if Modify_Tree_For_C
c7518e6f
AC
11825 and then Nkind (Parent (Exp)) = N_Object_Declaration
11826 and then
11827 (Nkind (Exp) /= N_Function_Call
11828 or else not Has_Discriminants (Exp_Type)
11829 or else Is_Internal_Name
11830 (Chars (Defining_Identifier (Parent (Exp)))))
11831 then
11832 goto Leave;
c269a1f5
AC
11833 end if;
11834
01957849
AC
11835 -- Special processing for function calls that return a limited type.
11836 -- We need to build a declaration that will enable build-in-place
11837 -- expansion of the call. This is not done if the context is already
11838 -- an object declaration, to prevent infinite recursion.
65df5b71
HK
11839
11840 -- This is relevant only in Ada 2005 mode. In Ada 95 programs we have
11841 -- to accommodate functions returning limited objects by reference.
11842
cc570be6
AC
11843 if Ada_Version >= Ada_2005
11844 and then Nkind (Exp) = N_Function_Call
51245e2d 11845 and then Is_Limited_View (Etype (Exp))
01957849 11846 and then Nkind (Parent (Exp)) /= N_Object_Declaration
65df5b71
HK
11847 then
11848 declare
faf387e1 11849 Obj : constant Entity_Id := Make_Temporary (Loc, 'F', Exp);
65df5b71
HK
11850 Decl : Node_Id;
11851
11852 begin
11853 Decl :=
11854 Make_Object_Declaration (Loc,
11855 Defining_Identifier => Obj,
11856 Object_Definition => New_Occurrence_Of (Exp_Type, Loc),
11857 Expression => Relocate_Node (Exp));
327503f1 11858
65df5b71
HK
11859 Insert_Action (Exp, Decl);
11860 Set_Etype (Obj, Exp_Type);
11861 Rewrite (Exp, New_Occurrence_Of (Obj, Loc));
67b8ac46 11862 goto Leave;
65df5b71
HK
11863 end;
11864 end if;
11865
2934b84a 11866 Def_Id := Build_Temporary (Loc, 'R', Exp);
70482933 11867
c269a1f5
AC
11868 -- The regular expansion of functions with side effects involves the
11869 -- generation of an access type to capture the return value found on
06b599fd 11870 -- the secondary stack. Since SPARK (and why) cannot process access
c269a1f5
AC
11871 -- types, use a different approach which ignores the secondary stack
11872 -- and "copies" the returned object.
7b52257c
AC
11873 -- When generating C code, no need for a 'reference since the
11874 -- secondary stack is not supported.
cc570be6 11875
c63a2ad6 11876 if GNATprove_Mode or Modify_Tree_For_C then
e4494292 11877 Res := New_Occurrence_Of (Def_Id, Loc);
c269a1f5
AC
11878 Ref_Type := Exp_Type;
11879
11880 -- Regular expansion utilizing an access type and 'reference
cc570be6 11881
c269a1f5
AC
11882 else
11883 Res :=
11884 Make_Explicit_Dereference (Loc,
e4494292 11885 Prefix => New_Occurrence_Of (Def_Id, Loc));
b2ab8c33 11886
c269a1f5
AC
11887 -- Generate:
11888 -- type Ann is access all <Exp_Type>;
cc570be6 11889
c269a1f5
AC
11890 Ref_Type := Make_Temporary (Loc, 'A');
11891
11892 Ptr_Typ_Decl :=
11893 Make_Full_Type_Declaration (Loc,
11894 Defining_Identifier => Ref_Type,
11895 Type_Definition =>
11896 Make_Access_To_Object_Definition (Loc,
11897 All_Present => True,
11898 Subtype_Indication =>
e4494292 11899 New_Occurrence_Of (Exp_Type, Loc)));
c269a1f5
AC
11900
11901 Insert_Action (Exp, Ptr_Typ_Decl);
11902 end if;
cc570be6
AC
11903
11904 E := Exp;
70482933
RK
11905 if Nkind (E) = N_Explicit_Dereference then
11906 New_Exp := Relocate_Node (Prefix (E));
365c8496 11907
70482933
RK
11908 else
11909 E := Relocate_Node (E);
cc570be6 11910
7b52257c
AC
11911 -- Do not generate a 'reference in SPARK mode or C generation
11912 -- since the access type is not created in the first place.
cc570be6 11913
c63a2ad6 11914 if GNATprove_Mode or Modify_Tree_For_C then
cc570be6 11915 New_Exp := E;
03e1048e
AC
11916
11917 -- Otherwise generate reference, marking the value as non-null
11918 -- since we know it cannot be null and we don't want a check.
11919
cc570be6
AC
11920 else
11921 New_Exp := Make_Reference (Loc, E);
74cab21a 11922 Set_Is_Known_Non_Null (Def_Id);
cc570be6 11923 end if;
70482933
RK
11924 end if;
11925
f44fe430
RD
11926 if Is_Delayed_Aggregate (E) then
11927
11928 -- The expansion of nested aggregates is delayed until the
11929 -- enclosing aggregate is expanded. As aggregates are often
273adcdf
AC
11930 -- qualified, the predicate applies to qualified expressions as
11931 -- well, indicating that the enclosing aggregate has not been
11932 -- expanded yet. At this point the aggregate is part of a
11933 -- stand-alone declaration, and must be fully expanded.
f44fe430
RD
11934
11935 if Nkind (E) = N_Qualified_Expression then
11936 Set_Expansion_Delayed (Expression (E), False);
11937 Set_Analyzed (Expression (E), False);
11938 else
11939 Set_Expansion_Delayed (E, False);
11940 end if;
11941
70482933
RK
11942 Set_Analyzed (E, False);
11943 end if;
11944
c7518e6f
AC
11945 -- Generating C code of object declarations that have discriminants
11946 -- and are initialized by means of a function call we propagate the
11947 -- discriminants of the parent type to the internally built object.
11948 -- This is needed to avoid generating an extra call to the called
11949 -- function.
11950
11951 -- For example, if we generate here the following declaration, it
11952 -- will be expanded later adding an extra call to evaluate the value
11953 -- of the discriminant (needed to compute the size of the object).
11954 --
11955 -- type Rec (D : Integer) is ...
11956 -- Obj : constant Rec := SomeFunc;
11957
c63a2ad6 11958 if Modify_Tree_For_C
c7518e6f
AC
11959 and then Nkind (Parent (Exp)) = N_Object_Declaration
11960 and then Has_Discriminants (Exp_Type)
11961 and then Nkind (Exp) = N_Function_Call
11962 then
11963 Insert_Action (Exp,
11964 Make_Object_Declaration (Loc,
11965 Defining_Identifier => Def_Id,
11966 Object_Definition => New_Copy_Tree
11967 (Object_Definition (Parent (Exp))),
11968 Constant_Present => True,
11969 Expression => New_Exp));
11970 else
11971 Insert_Action (Exp,
11972 Make_Object_Declaration (Loc,
11973 Defining_Identifier => Def_Id,
11974 Object_Definition => New_Occurrence_Of (Ref_Type, Loc),
11975 Constant_Present => True,
11976 Expression => New_Exp));
11977 end if;
70482933
RK
11978 end if;
11979
273adcdf
AC
11980 -- Preserve the Assignment_OK flag in all copies, since at least one
11981 -- copy may be used in a context where this flag must be set (otherwise
11982 -- why would the flag be set in the first place).
70482933
RK
11983
11984 Set_Assignment_OK (Res, Assignment_OK (Exp));
11985
134f52b9 11986 -- Preserve the Do_Range_Check flag in all copies
5da54433
JM
11987
11988 Set_Do_Range_Check (Res, Do_Range_Check (Exp));
11989
70482933
RK
11990 -- Finally rewrite the original expression and we are done
11991
11992 Rewrite (Exp, Res);
11993 Analyze_And_Resolve (Exp, Exp_Type);
67b8ac46
AC
11994
11995 <<Leave>>
70482933
RK
11996 Scope_Suppress := Svg_Suppress;
11997 end Remove_Side_Effects;
11998
b619c88e
AC
11999 ------------------------
12000 -- Replace_References --
12001 ------------------------
12002
12003 procedure Replace_References
12004 (Expr : Node_Id;
12005 Par_Typ : Entity_Id;
12006 Deriv_Typ : Entity_Id;
12007 Par_Obj : Entity_Id := Empty;
12008 Deriv_Obj : Entity_Id := Empty)
12009 is
12010 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean;
12011 -- Determine whether node Ref denotes some component of Deriv_Obj
12012
12013 function Replace_Ref (Ref : Node_Id) return Traverse_Result;
12014 -- Substitute a reference to an entity with the corresponding value
12015 -- stored in table Type_Map.
12016
12017 function Type_Of_Formal
12018 (Call : Node_Id;
12019 Actual : Node_Id) return Entity_Id;
12020 -- Find the type of the formal parameter which corresponds to actual
12021 -- parameter Actual in subprogram call Call.
12022
12023 ----------------------
12024 -- Is_Deriv_Obj_Ref --
12025 ----------------------
12026
12027 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean is
12028 Par : constant Node_Id := Parent (Ref);
12029
12030 begin
12031 -- Detect the folowing selected component form:
12032
12033 -- Deriv_Obj.(something)
12034
12035 return
12036 Nkind (Par) = N_Selected_Component
12037 and then Is_Entity_Name (Prefix (Par))
12038 and then Entity (Prefix (Par)) = Deriv_Obj;
12039 end Is_Deriv_Obj_Ref;
12040
12041 -----------------
12042 -- Replace_Ref --
12043 -----------------
12044
12045 function Replace_Ref (Ref : Node_Id) return Traverse_Result is
b554177a 12046 procedure Remove_Controlling_Arguments (From_Arg : Node_Id);
ca0b6141 12047 -- Reset the Controlling_Argument of all function calls that
b554177a
AC
12048 -- encapsulate node From_Arg.
12049
12050 ----------------------------------
12051 -- Remove_Controlling_Arguments --
12052 ----------------------------------
12053
12054 procedure Remove_Controlling_Arguments (From_Arg : Node_Id) is
12055 Par : Node_Id;
12056
12057 begin
12058 Par := From_Arg;
12059 while Present (Par) loop
12060 if Nkind (Par) = N_Function_Call
12061 and then Present (Controlling_Argument (Par))
12062 then
12063 Set_Controlling_Argument (Par, Empty);
12064
12065 -- Prevent the search from going too far
12066
12067 elsif Is_Body_Or_Package_Declaration (Par) then
12068 exit;
12069 end if;
12070
12071 Par := Parent (Par);
12072 end loop;
12073 end Remove_Controlling_Arguments;
12074
12075 -- Local variables
12076
b619c88e
AC
12077 Context : constant Node_Id := Parent (Ref);
12078 Loc : constant Source_Ptr := Sloc (Ref);
12079 Ref_Id : Entity_Id;
12080 Result : Traverse_Result;
12081
12082 New_Ref : Node_Id;
12083 -- The new reference which is intended to substitute the old one
12084
12085 Old_Ref : Node_Id;
12086 -- The reference designated for replacement. In certain cases this
12087 -- may be a node other than Ref.
12088
12089 Val : Node_Or_Entity_Id;
12090 -- The corresponding value of Ref from the type map
12091
b554177a
AC
12092 -- Start of processing for Replace_Ref
12093
b619c88e
AC
12094 begin
12095 -- Assume that the input reference is to be replaced and that the
12096 -- traversal should examine the children of the reference.
12097
12098 Old_Ref := Ref;
12099 Result := OK;
12100
12101 -- The input denotes a meaningful reference
12102
12103 if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then
12104 Ref_Id := Entity (Ref);
12105 Val := Type_Map.Get (Ref_Id);
12106
12107 -- The reference has a corresponding value in the type map, a
12108 -- substitution is possible.
12109
12110 if Present (Val) then
12111
12112 -- The reference denotes a discriminant
12113
12114 if Ekind (Ref_Id) = E_Discriminant then
12115 if Nkind (Val) in N_Entity then
12116
12117 -- The value denotes another discriminant. Replace as
12118 -- follows:
12119
12120 -- _object.Discr -> _object.Val
12121
12122 if Ekind (Val) = E_Discriminant then
12123 New_Ref := New_Occurrence_Of (Val, Loc);
12124
12125 -- Otherwise the value denotes the entity of a name which
12126 -- constraints the discriminant. Replace as follows:
12127
12128 -- _object.Discr -> Val
12129
12130 else
12131 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
12132
12133 New_Ref := New_Occurrence_Of (Val, Loc);
12134 Old_Ref := Parent (Old_Ref);
12135 end if;
12136
12137 -- Otherwise the value denotes an arbitrary expression which
12138 -- constraints the discriminant. Replace as follows:
12139
12140 -- _object.Discr -> Val
12141
12142 else
12143 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref));
12144
12145 New_Ref := New_Copy_Tree (Val);
12146 Old_Ref := Parent (Old_Ref);
12147 end if;
12148
12149 -- Otherwise the reference denotes a primitive. Replace as
12150 -- follows:
12151
12152 -- Primitive -> Val
12153
12154 else
12155 pragma Assert (Nkind (Val) in N_Entity);
12156 New_Ref := New_Occurrence_Of (Val, Loc);
12157 end if;
12158
12159 -- The reference mentions the _object parameter of the parent
b554177a 12160 -- type's DIC or type invariant procedure. Replace as follows:
b619c88e
AC
12161
12162 -- _object -> _object
12163
12164 elsif Present (Par_Obj)
12165 and then Present (Deriv_Obj)
12166 and then Ref_Id = Par_Obj
12167 then
12168 New_Ref := New_Occurrence_Of (Deriv_Obj, Loc);
12169
b554177a 12170 -- The type of the _object parameter is class-wide when the
ca0b6141 12171 -- expression comes from an assertion pragma that applies to
b554177a
AC
12172 -- an abstract parent type or an interface. The class-wide type
12173 -- facilitates the preanalysis of the expression by treating
ca0b6141 12174 -- calls to abstract primitives that mention the current
b554177a
AC
12175 -- instance of the type as dispatching. Once the calls are
12176 -- remapped to invoke overriding or inherited primitives, the
12177 -- calls no longer need to be dispatching. Examine all function
ca0b6141 12178 -- calls that encapsulate the _object parameter and reset their
b554177a
AC
12179 -- Controlling_Argument attribute.
12180
12181 if Is_Class_Wide_Type (Etype (Par_Obj))
12182 and then Is_Abstract_Type (Root_Type (Etype (Par_Obj)))
12183 then
12184 Remove_Controlling_Arguments (Old_Ref);
12185 end if;
12186
b619c88e
AC
12187 -- The reference to _object acts as an actual parameter in a
12188 -- subprogram call which may be invoking a primitive of the
12189 -- parent type:
12190
12191 -- Primitive (... _object ...);
12192
12193 -- The parent type primitive may not be overridden nor
12194 -- inherited when it is declared after the derived type
12195 -- definition:
12196
12197 -- type Parent is tagged private;
12198 -- type Child is new Parent with private;
12199 -- procedure Primitive (Obj : Parent);
12200
12201 -- In this scenario the _object parameter is converted to the
12202 -- parent type. Due to complications with partial/full views
12203 -- and view swaps, the parent type is taken from the formal
12204 -- parameter of the subprogram being called.
12205
612c48b1 12206 if Nkind (Context) in N_Subprogram_Call
b619c88e
AC
12207 and then No (Type_Map.Get (Entity (Name (Context))))
12208 then
76f9c7f4
BD
12209 declare
12210 -- We need to use the Original_Node of the callee, in
12211 -- case it was already modified. Note that we are using
12212 -- Traverse_Proc to walk the tree, and it is defined to
12213 -- walk subtrees in an arbitrary order.
12214
12215 Callee : constant Entity_Id :=
12216 Entity (Original_Node (Name (Context)));
12217 begin
12218 if No (Type_Map.Get (Callee)) then
12219 New_Ref :=
12220 Convert_To
12221 (Type_Of_Formal (Context, Old_Ref), New_Ref);
12222
12223 -- Do not process the generated type conversion
12224 -- because both the parent type and the derived type
12225 -- are in the Type_Map table. This will clobber the
12226 -- type conversion by resetting its subtype mark.
12227
12228 Result := Skip;
12229 end if;
12230 end;
b619c88e
AC
12231 end if;
12232
12233 -- Otherwise there is nothing to replace
12234
12235 else
12236 New_Ref := Empty;
12237 end if;
12238
12239 if Present (New_Ref) then
12240 Rewrite (Old_Ref, New_Ref);
12241
12242 -- Update the return type when the context of the reference
12243 -- acts as the name of a function call. Note that the update
12244 -- should not be performed when the reference appears as an
12245 -- actual in the call.
12246
12247 if Nkind (Context) = N_Function_Call
12248 and then Name (Context) = Old_Ref
12249 then
12250 Set_Etype (Context, Etype (Val));
12251 end if;
12252 end if;
12253 end if;
12254
12255 -- Reanalyze the reference due to potential replacements
12256
12257 if Nkind (Old_Ref) in N_Has_Etype then
12258 Set_Analyzed (Old_Ref, False);
12259 end if;
12260
12261 return Result;
12262 end Replace_Ref;
12263
12264 procedure Replace_Refs is new Traverse_Proc (Replace_Ref);
12265
12266 --------------------
12267 -- Type_Of_Formal --
12268 --------------------
12269
12270 function Type_Of_Formal
12271 (Call : Node_Id;
12272 Actual : Node_Id) return Entity_Id
12273 is
12274 A : Node_Id;
12275 F : Entity_Id;
12276
12277 begin
12278 -- Examine the list of actual and formal parameters in parallel
12279
12280 A := First (Parameter_Associations (Call));
12281 F := First_Formal (Entity (Name (Call)));
12282 while Present (A) and then Present (F) loop
12283 if A = Actual then
12284 return Etype (F);
12285 end if;
12286
12287 Next (A);
12288 Next_Formal (F);
12289 end loop;
12290
12291 -- The actual parameter must always have a corresponding formal
12292
12293 pragma Assert (False);
12294
12295 return Empty;
12296 end Type_Of_Formal;
12297
12298 -- Start of processing for Replace_References
12299
12300 begin
12301 -- Map the attributes of the parent type to the proper corresponding
12302 -- attributes of the derived type.
12303
12304 Map_Types
12305 (Parent_Type => Par_Typ,
12306 Derived_Type => Deriv_Typ);
12307
12308 -- Inspect the input expression and perform substitutions where
12309 -- necessary.
12310
12311 Replace_Refs (Expr);
12312 end Replace_References;
12313
12314 -----------------------------
12315 -- Replace_Type_References --
12316 -----------------------------
12317
12318 procedure Replace_Type_References
b554177a
AC
12319 (Expr : Node_Id;
12320 Typ : Entity_Id;
12321 Obj_Id : Entity_Id)
b619c88e
AC
12322 is
12323 procedure Replace_Type_Ref (N : Node_Id);
12324 -- Substitute a single reference of the current instance of type Typ
12325 -- with a reference to Obj_Id.
12326
12327 ----------------------
12328 -- Replace_Type_Ref --
12329 ----------------------
12330
12331 procedure Replace_Type_Ref (N : Node_Id) is
b619c88e
AC
12332 begin
12333 -- Decorate the reference to Typ even though it may be rewritten
65f1ca2e
AC
12334 -- further down. This is done so that routines which examine
12335 -- properties of the Original_Node have some semantic information.
b619c88e
AC
12336
12337 if Nkind (N) = N_Identifier then
12338 Set_Entity (N, Typ);
12339 Set_Etype (N, Typ);
12340
12341 elsif Nkind (N) = N_Selected_Component then
12342 Analyze (Prefix (N));
12343 Set_Entity (Selector_Name (N), Typ);
12344 Set_Etype (Selector_Name (N), Typ);
12345 end if;
12346
12347 -- Perform the following substitution:
12348
b554177a 12349 -- Typ --> _object
51148dda 12350
b554177a 12351 Rewrite (N, New_Occurrence_Of (Obj_Id, Sloc (N)));
b619c88e
AC
12352 Set_Comes_From_Source (N, True);
12353 end Replace_Type_Ref;
12354
12355 procedure Replace_Type_Refs is
12356 new Replace_Type_References_Generic (Replace_Type_Ref);
12357
12358 -- Start of processing for Replace_Type_References
12359
12360 begin
12361 Replace_Type_Refs (Expr, Typ);
12362 end Replace_Type_References;
12363
f44fe430
RD
12364 ---------------------------
12365 -- Represented_As_Scalar --
12366 ---------------------------
12367
12368 function Represented_As_Scalar (T : Entity_Id) return Boolean is
12369 UT : constant Entity_Id := Underlying_Type (T);
12370 begin
12371 return Is_Scalar_Type (UT)
12372 or else (Is_Bit_Packed_Array (UT)
8ca597af 12373 and then Is_Scalar_Type (Packed_Array_Impl_Type (UT)));
f44fe430
RD
12374 end Represented_As_Scalar;
12375
87729e5a
AC
12376 ------------------------------
12377 -- Requires_Cleanup_Actions --
12378 ------------------------------
12379
fcf848c4
AC
12380 function Requires_Cleanup_Actions
12381 (N : Node_Id;
12382 Lib_Level : Boolean) return Boolean
12383 is
5f44f0d4 12384 At_Lib_Level : constant Boolean :=
4a08c95c
AC
12385 Lib_Level
12386 and then Nkind (N) in N_Package_Body | N_Package_Specification;
fcf848c4 12387 -- N is at the library level if the top-most context is a package and
3f833dc2 12388 -- the path taken to reach N does not include nonpackage constructs.
87729e5a
AC
12389
12390 begin
12391 case Nkind (N) is
d8f43ee6
HK
12392 when N_Accept_Statement
12393 | N_Block_Statement
12394 | N_Entry_Body
12395 | N_Package_Body
12396 | N_Protected_Body
12397 | N_Subprogram_Body
12398 | N_Task_Body
12399 =>
87729e5a 12400 return
c581c520
PMR
12401 Requires_Cleanup_Actions
12402 (L => Declarations (N),
12403 Lib_Level => At_Lib_Level,
12404 Nested_Constructs => True)
12405 or else
12406 (Present (Handled_Statement_Sequence (N))
12407 and then
12408 Requires_Cleanup_Actions
12409 (L =>
12410 Statements (Handled_Statement_Sequence (N)),
12411 Lib_Level => At_Lib_Level,
12412 Nested_Constructs => True));
40c21e91
PMR
12413
12414 -- Extended return statements are the same as the above, except that
12415 -- there is no Declarations field. We do not want to clean up the
12416 -- Return_Object_Declarations.
12417
12418 when N_Extended_Return_Statement =>
12419 return
c581c520
PMR
12420 Present (Handled_Statement_Sequence (N))
12421 and then Requires_Cleanup_Actions
12422 (L =>
12423 Statements (Handled_Statement_Sequence (N)),
12424 Lib_Level => At_Lib_Level,
12425 Nested_Constructs => True);
87729e5a
AC
12426
12427 when N_Package_Specification =>
12428 return
c581c520
PMR
12429 Requires_Cleanup_Actions
12430 (L => Visible_Declarations (N),
12431 Lib_Level => At_Lib_Level,
12432 Nested_Constructs => True)
12433 or else
12434 Requires_Cleanup_Actions
12435 (L => Private_Declarations (N),
12436 Lib_Level => At_Lib_Level,
12437 Nested_Constructs => True);
87729e5a 12438
d8f43ee6 12439 when others =>
40c21e91 12440 raise Program_Error;
87729e5a
AC
12441 end case;
12442 end Requires_Cleanup_Actions;
12443
12444 ------------------------------
12445 -- Requires_Cleanup_Actions --
12446 ------------------------------
12447
12448 function Requires_Cleanup_Actions
2ba7e31e 12449 (L : List_Id;
fcf848c4 12450 Lib_Level : Boolean;
2ba7e31e 12451 Nested_Constructs : Boolean) return Boolean
87729e5a
AC
12452 is
12453 Decl : Node_Id;
12454 Expr : Node_Id;
12455 Obj_Id : Entity_Id;
12456 Obj_Typ : Entity_Id;
12457 Pack_Id : Entity_Id;
12458 Typ : Entity_Id;
12459
12460 begin
a3d1ca01 12461 if No (L) or else Is_Empty_List (L) then
87729e5a
AC
12462 return False;
12463 end if;
12464
12465 Decl := First (L);
12466 while Present (Decl) loop
12467
12468 -- Library-level tagged types
12469
12470 if Nkind (Decl) = N_Full_Type_Declaration then
12471 Typ := Defining_Identifier (Decl);
12472
8636f52f
HK
12473 -- Ignored Ghost types do not need any cleanup actions because
12474 -- they will not appear in the final tree.
12475
12476 if Is_Ignored_Ghost_Entity (Typ) then
12477 null;
12478
12479 elsif Is_Tagged_Type (Typ)
87729e5a
AC
12480 and then Is_Library_Level_Entity (Typ)
12481 and then Convention (Typ) = Convention_Ada
12482 and then Present (Access_Disp_Table (Typ))
12483 and then RTE_Available (RE_Unregister_Tag)
87729e5a 12484 and then not Is_Abstract_Type (Typ)
8636f52f 12485 and then not No_Run_Time_Mode
87729e5a
AC
12486 then
12487 return True;
12488 end if;
12489
12490 -- Regular object declarations
12491
12492 elsif Nkind (Decl) = N_Object_Declaration then
12493 Obj_Id := Defining_Identifier (Decl);
12494 Obj_Typ := Base_Type (Etype (Obj_Id));
12495 Expr := Expression (Decl);
12496
12497 -- Bypass any form of processing for objects which have their
12498 -- finalization disabled. This applies only to objects at the
12499 -- library level.
12500
fcf848c4 12501 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
87729e5a
AC
12502 null;
12503
937e9676
AC
12504 -- Finalization of transient objects are treated separately in
12505 -- order to handle sensitive cases. These include:
87729e5a 12506
937e9676
AC
12507 -- * Aggregate expansion
12508 -- * If, case, and expression with actions expansion
12509 -- * Transient scopes
12510
12511 -- If one of those contexts has marked the transient object as
12512 -- ignored, do not generate finalization actions for it.
12513
12514 elsif Is_Finalized_Transient (Obj_Id)
12515 or else Is_Ignored_Transient (Obj_Id)
12516 then
87729e5a
AC
12517 null;
12518
8636f52f
HK
12519 -- Ignored Ghost objects do not need any cleanup actions because
12520 -- they will not appear in the final tree.
12521
12522 elsif Is_Ignored_Ghost_Entity (Obj_Id) then
12523 null;
12524
87729e5a 12525 -- The object is of the form:
3386e3ae 12526 -- Obj : [constant] Typ [:= Expr];
87729e5a 12527 --
3386e3ae
AC
12528 -- Do not process tag-to-class-wide conversions because they do
12529 -- not yield an object. Do not process the incomplete view of a
12530 -- deferred constant. Note that an object initialized by means
12531 -- of a build-in-place function call may appear as a deferred
12532 -- constant after expansion activities. These kinds of objects
12533 -- must be finalized.
87729e5a
AC
12534
12535 elsif not Is_Imported (Obj_Id)
12536 and then Needs_Finalization (Obj_Typ)
aab08130 12537 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id)
3386e3ae
AC
12538 and then not (Ekind (Obj_Id) = E_Constant
12539 and then not Has_Completion (Obj_Id)
12540 and then No (BIP_Initialization_Call (Obj_Id)))
87729e5a
AC
12541 then
12542 return True;
12543
12544 -- The object is of the form:
12545 -- Obj : Access_Typ := Non_BIP_Function_Call'reference;
12546 --
12547 -- Obj : Access_Typ :=
cdc96e3e 12548 -- BIP_Function_Call (BIPalloc => 2, ...)'reference;
87729e5a
AC
12549
12550 elsif Is_Access_Type (Obj_Typ)
12551 and then Needs_Finalization
12552 (Available_View (Designated_Type (Obj_Typ)))
12553 and then Present (Expr)
12554 and then
cdc96e3e
AC
12555 (Is_Secondary_Stack_BIP_Func_Call (Expr)
12556 or else
12557 (Is_Non_BIP_Func_Call (Expr)
12558 and then not Is_Related_To_Func_Return (Obj_Id)))
87729e5a
AC
12559 then
12560 return True;
12561
937e9676
AC
12562 -- Processing for "hook" objects generated for transient objects
12563 -- declared inside an Expression_With_Actions.
87729e5a
AC
12564
12565 elsif Is_Access_Type (Obj_Typ)
3cebd1c0
AC
12566 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12567 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
c5c780e6 12568 N_Object_Declaration
3cebd1c0
AC
12569 then
12570 return True;
12571
9b16cb57
RD
12572 -- Processing for intermediate results of if expressions where
12573 -- one of the alternatives uses a controlled function call.
3cebd1c0
AC
12574
12575 elsif Is_Access_Type (Obj_Typ)
12576 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
12577 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) =
9ab5d86b 12578 N_Defining_Identifier
3cebd1c0
AC
12579 and then Present (Expr)
12580 and then Nkind (Expr) = N_Null
87729e5a
AC
12581 then
12582 return True;
12583
12584 -- Simple protected objects which use type System.Tasking.
12585 -- Protected_Objects.Protection to manage their locks should be
12586 -- treated as controlled since they require manual cleanup.
12587
12588 elsif Ekind (Obj_Id) = E_Variable
c5c780e6
HK
12589 and then (Is_Simple_Protected_Type (Obj_Typ)
12590 or else Has_Simple_Protected_Object (Obj_Typ))
87729e5a
AC
12591 then
12592 return True;
12593 end if;
12594
12595 -- Specific cases of object renamings
12596
aab08130 12597 elsif Nkind (Decl) = N_Object_Renaming_Declaration then
87729e5a
AC
12598 Obj_Id := Defining_Identifier (Decl);
12599 Obj_Typ := Base_Type (Etype (Obj_Id));
12600
12601 -- Bypass any form of processing for objects which have their
12602 -- finalization disabled. This applies only to objects at the
12603 -- library level.
12604
fcf848c4 12605 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then
87729e5a
AC
12606 null;
12607
8636f52f
HK
12608 -- Ignored Ghost object renamings do not need any cleanup actions
12609 -- because they will not appear in the final tree.
12610
12611 elsif Is_Ignored_Ghost_Entity (Obj_Id) then
12612 null;
12613
87729e5a
AC
12614 -- Return object of a build-in-place function. This case is
12615 -- recognized and marked by the expansion of an extended return
12616 -- statement (see Expand_N_Extended_Return_Statement).
12617
12618 elsif Needs_Finalization (Obj_Typ)
12619 and then Is_Return_Object (Obj_Id)
3cebd1c0 12620 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
87729e5a
AC
12621 then
12622 return True;
aab08130 12623
a429e6b3
AC
12624 -- Detect a case where a source object has been initialized by
12625 -- a controlled function call or another object which was later
12626 -- rewritten as a class-wide conversion of Ada.Tags.Displace.
aab08130 12627
a429e6b3
AC
12628 -- Obj1 : CW_Type := Src_Obj;
12629 -- Obj2 : CW_Type := Function_Call (...);
aab08130 12630
a429e6b3
AC
12631 -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
12632 -- Tmp : ... := Function_Call (...)'reference;
12633 -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
aab08130 12634
a429e6b3 12635 elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
aab08130 12636 return True;
87729e5a
AC
12637 end if;
12638
d3f70b35
AC
12639 -- Inspect the freeze node of an access-to-controlled type and look
12640 -- for a delayed finalization master. This case arises when the
12641 -- freeze actions are inserted at a later time than the expansion of
12642 -- the context. Since Build_Finalizer is never called on a single
12643 -- construct twice, the master will be ultimately left out and never
12644 -- finalized. This is also needed for freeze actions of designated
12645 -- types themselves, since in some cases the finalization master is
12646 -- associated with a designated type's freeze node rather than that
12647 -- of the access type (see handling for freeze actions in
12648 -- Build_Finalization_Master).
87729e5a
AC
12649
12650 elsif Nkind (Decl) = N_Freeze_Entity
12651 and then Present (Actions (Decl))
12652 then
12653 Typ := Entity (Decl);
12654
8636f52f
HK
12655 -- Freeze nodes for ignored Ghost types do not need cleanup
12656 -- actions because they will never appear in the final tree.
12657
12658 if Is_Ignored_Ghost_Entity (Typ) then
12659 null;
12660
5af3a22a 12661 elsif ((Is_Access_Object_Type (Typ)
8636f52f
HK
12662 and then Needs_Finalization
12663 (Available_View (Designated_Type (Typ))))
12664 or else (Is_Type (Typ) and then Needs_Finalization (Typ)))
8f66cda7 12665 and then Requires_Cleanup_Actions
fcf848c4 12666 (Actions (Decl), Lib_Level, Nested_Constructs)
87729e5a
AC
12667 then
12668 return True;
12669 end if;
12670
12671 -- Nested package declarations
12672
2ba7e31e
AC
12673 elsif Nested_Constructs
12674 and then Nkind (Decl) = N_Package_Declaration
12675 then
8636f52f 12676 Pack_Id := Defining_Entity (Decl);
87729e5a 12677
8636f52f
HK
12678 -- Do not inspect an ignored Ghost package because all code found
12679 -- within will not appear in the final tree.
87729e5a 12680
8636f52f
HK
12681 if Is_Ignored_Ghost_Entity (Pack_Id) then
12682 null;
12683
12684 elsif Ekind (Pack_Id) /= E_Generic_Package
12685 and then Requires_Cleanup_Actions
12686 (Specification (Decl), Lib_Level)
87729e5a
AC
12687 then
12688 return True;
12689 end if;
12690
12691 -- Nested package bodies
12692
0e564ab4 12693 elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then
87729e5a 12694
8636f52f
HK
12695 -- Do not inspect an ignored Ghost package body because all code
12696 -- found within will not appear in the final tree.
12697
12698 if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then
12699 null;
12700
12701 elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package
fcf848c4 12702 and then Requires_Cleanup_Actions (Decl, Lib_Level)
87729e5a
AC
12703 then
12704 return True;
12705 end if;
8636f52f
HK
12706
12707 elsif Nkind (Decl) = N_Block_Statement
12708 and then
12709
937e9676 12710 -- Handle a rare case caused by a controlled transient object
8636f52f
HK
12711 -- created as part of a record init proc. The variable is wrapped
12712 -- in a block, but the block is not associated with a transient
12713 -- scope.
12714
12715 (Inside_Init_Proc
12716
12717 -- Handle the case where the original context has been wrapped in
12718 -- a block to avoid interference between exception handlers and
12719 -- At_End handlers. Treat the block as transparent and process its
12720 -- contents.
12721
12722 or else Is_Finalization_Wrapper (Decl))
12723 then
12724 if Requires_Cleanup_Actions (Decl, Lib_Level) then
12725 return True;
12726 end if;
87729e5a
AC
12727 end if;
12728
12729 Next (Decl);
12730 end loop;
12731
12732 return False;
12733 end Requires_Cleanup_Actions;
12734
70482933
RK
12735 ------------------------------------
12736 -- Safe_Unchecked_Type_Conversion --
12737 ------------------------------------
12738
273adcdf
AC
12739 -- Note: this function knows quite a bit about the exact requirements of
12740 -- Gigi with respect to unchecked type conversions, and its code must be
12741 -- coordinated with any changes in Gigi in this area.
70482933
RK
12742
12743 -- The above requirements should be documented in Sinfo ???
12744
12745 function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is
12746 Otyp : Entity_Id;
12747 Ityp : Entity_Id;
12748 Oalign : Uint;
12749 Ialign : Uint;
12750 Pexp : constant Node_Id := Parent (Exp);
12751
12752 begin
12753 -- If the expression is the RHS of an assignment or object declaration
0cc1540d 12754 -- we are always OK because there will always be a target.
70482933
RK
12755
12756 -- Object renaming declarations, (generated for view conversions of
12757 -- actuals in inlined calls), like object declarations, provide an
12758 -- explicit type, and are safe as well.
12759
12760 if (Nkind (Pexp) = N_Assignment_Statement
12761 and then Expression (Pexp) = Exp)
4a08c95c
AC
12762 or else Nkind (Pexp)
12763 in N_Object_Declaration | N_Object_Renaming_Declaration
70482933
RK
12764 then
12765 return True;
12766
273adcdf
AC
12767 -- If the expression is the prefix of an N_Selected_Component we should
12768 -- also be OK because GCC knows to look inside the conversion except if
12769 -- the type is discriminated. We assume that we are OK anyway if the
12770 -- type is not set yet or if it is controlled since we can't afford to
12771 -- introduce a temporary in this case.
70482933
RK
12772
12773 elsif Nkind (Pexp) = N_Selected_Component
0e564ab4 12774 and then Prefix (Pexp) = Exp
70482933 12775 then
12ad5b9c
EB
12776 return No (Etype (Pexp))
12777 or else not Is_Type (Etype (Pexp))
12778 or else not Has_Discriminants (Etype (Pexp))
12779 or else Is_Constrained (Etype (Pexp));
70482933
RK
12780 end if;
12781
273adcdf
AC
12782 -- Set the output type, this comes from Etype if it is set, otherwise we
12783 -- take it from the subtype mark, which we assume was already fully
12784 -- analyzed.
70482933
RK
12785
12786 if Present (Etype (Exp)) then
12787 Otyp := Etype (Exp);
12788 else
12789 Otyp := Entity (Subtype_Mark (Exp));
12790 end if;
12791
0cc1540d
AC
12792 -- The input type always comes from the expression, and we assume this
12793 -- is indeed always analyzed, so we can simply get the Etype.
70482933
RK
12794
12795 Ityp := Etype (Expression (Exp));
12796
12797 -- Initialize alignments to unknown so far
12798
12799 Oalign := No_Uint;
12800 Ialign := No_Uint;
12801
273adcdf
AC
12802 -- Replace a concurrent type by its corresponding record type and each
12803 -- type by its underlying type and do the tests on those. The original
12804 -- type may be a private type whose completion is a concurrent type, so
12805 -- find the underlying type first.
70482933
RK
12806
12807 if Present (Underlying_Type (Otyp)) then
12808 Otyp := Underlying_Type (Otyp);
12809 end if;
12810
12811 if Present (Underlying_Type (Ityp)) then
12812 Ityp := Underlying_Type (Ityp);
12813 end if;
12814
12815 if Is_Concurrent_Type (Otyp) then
12816 Otyp := Corresponding_Record_Type (Otyp);
12817 end if;
12818
12819 if Is_Concurrent_Type (Ityp) then
12820 Ityp := Corresponding_Record_Type (Ityp);
12821 end if;
12822
12823 -- If the base types are the same, we know there is no problem since
12824 -- this conversion will be a noop.
12825
12826 if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then
12827 return True;
12828
6cdb2c6e
AC
12829 -- Same if this is an upwards conversion of an untagged type, and there
12830 -- are no constraints involved (could be more general???)
12831
12832 elsif Etype (Ityp) = Otyp
12833 and then not Is_Tagged_Type (Ityp)
12834 and then not Has_Discriminants (Ityp)
12835 and then No (First_Rep_Item (Base_Type (Ityp)))
12836 then
12837 return True;
12838
273adcdf
AC
12839 -- If the expression has an access type (object or subprogram) we assume
12840 -- that the conversion is safe, because the size of the target is safe,
12841 -- even if it is a record (which might be treated as having unknown size
12842 -- at this point).
4da17013
AC
12843
12844 elsif Is_Access_Type (Ityp) then
12845 return True;
12846
273adcdf
AC
12847 -- If the size of output type is known at compile time, there is never
12848 -- a problem. Note that unconstrained records are considered to be of
12849 -- known size, but we can't consider them that way here, because we are
12850 -- talking about the actual size of the object.
70482933 12851
273adcdf
AC
12852 -- We also make sure that in addition to the size being known, we do not
12853 -- have a case which might generate an embarrassingly large temp in
12854 -- stack checking mode.
70482933
RK
12855
12856 elsif Size_Known_At_Compile_Time (Otyp)
7324bf49
AC
12857 and then
12858 (not Stack_Checking_Enabled
0e564ab4 12859 or else not May_Generate_Large_Temp (Otyp))
70482933
RK
12860 and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp))
12861 then
12862 return True;
12863
0cc1540d
AC
12864 -- If either type is tagged, then we know the alignment is OK so Gigi
12865 -- will be able to use pointer punning.
70482933
RK
12866
12867 elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then
12868 return True;
12869
273adcdf
AC
12870 -- If either type is a limited record type, we cannot do a copy, so say
12871 -- safe since there's nothing else we can do.
70482933
RK
12872
12873 elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then
12874 return True;
12875
12876 -- Conversions to and from packed array types are always ignored and
12877 -- hence are safe.
12878
8ca597af
RD
12879 elsif Is_Packed_Array_Impl_Type (Otyp)
12880 or else Is_Packed_Array_Impl_Type (Ityp)
70482933
RK
12881 then
12882 return True;
12883 end if;
12884
12885 -- The only other cases known to be safe is if the input type's
12886 -- alignment is known to be at least the maximum alignment for the
12887 -- target or if both alignments are known and the output type's
273adcdf 12888 -- alignment is no stricter than the input's. We can use the component
ff7b374b 12889 -- type alignment for an array if a type is an unpacked array type.
70482933
RK
12890
12891 if Present (Alignment_Clause (Otyp)) then
12892 Oalign := Expr_Value (Expression (Alignment_Clause (Otyp)));
12893
12894 elsif Is_Array_Type (Otyp)
12895 and then Present (Alignment_Clause (Component_Type (Otyp)))
12896 then
12897 Oalign := Expr_Value (Expression (Alignment_Clause
12898 (Component_Type (Otyp))));
12899 end if;
12900
12901 if Present (Alignment_Clause (Ityp)) then
12902 Ialign := Expr_Value (Expression (Alignment_Clause (Ityp)));
12903
12904 elsif Is_Array_Type (Ityp)
12905 and then Present (Alignment_Clause (Component_Type (Ityp)))
12906 then
12907 Ialign := Expr_Value (Expression (Alignment_Clause
12908 (Component_Type (Ityp))));
12909 end if;
12910
12911 if Ialign /= No_Uint and then Ialign > Maximum_Alignment then
12912 return True;
12913
c5c780e6
HK
12914 elsif Ialign /= No_Uint
12915 and then Oalign /= No_Uint
70482933
RK
12916 and then Ialign <= Oalign
12917 then
12918 return True;
12919
bebbff91 12920 -- Otherwise, Gigi cannot handle this and we must make a temporary
70482933
RK
12921
12922 else
12923 return False;
12924 end if;
70482933
RK
12925 end Safe_Unchecked_Type_Conversion;
12926
05350ac6
BD
12927 ---------------------------------
12928 -- Set_Current_Value_Condition --
12929 ---------------------------------
12930
12931 -- Note: the implementation of this procedure is very closely tied to the
12932 -- implementation of Get_Current_Value_Condition. Here we set required
12933 -- Current_Value fields, and in Get_Current_Value_Condition, we interpret
12934 -- them, so they must have a consistent view.
12935
12936 procedure Set_Current_Value_Condition (Cnode : Node_Id) is
12937
12938 procedure Set_Entity_Current_Value (N : Node_Id);
12939 -- If N is an entity reference, where the entity is of an appropriate
12940 -- kind, then set the current value of this entity to Cnode, unless
12941 -- there is already a definite value set there.
12942
12943 procedure Set_Expression_Current_Value (N : Node_Id);
12944 -- If N is of an appropriate form, sets an appropriate entry in current
12945 -- value fields of relevant entities. Multiple entities can be affected
12946 -- in the case of an AND or AND THEN.
12947
12948 ------------------------------
12949 -- Set_Entity_Current_Value --
12950 ------------------------------
12951
12952 procedure Set_Entity_Current_Value (N : Node_Id) is
12953 begin
12954 if Is_Entity_Name (N) then
12955 declare
12956 Ent : constant Entity_Id := Entity (N);
12957
12958 begin
12959 -- Don't capture if not safe to do so
12960
12961 if not Safe_To_Capture_Value (N, Ent, Cond => True) then
12962 return;
12963 end if;
12964
273adcdf
AC
12965 -- Here we have a case where the Current_Value field may need
12966 -- to be set. We set it if it is not already set to a compile
12967 -- time expression value.
05350ac6
BD
12968
12969 -- Note that this represents a decision that one condition
273adcdf
AC
12970 -- blots out another previous one. That's certainly right if
12971 -- they occur at the same level. If the second one is nested,
12972 -- then the decision is neither right nor wrong (it would be
12973 -- equally OK to leave the outer one in place, or take the new
8e334288 12974 -- inner one). Really we should record both, but our data
273adcdf 12975 -- structures are not that elaborate.
05350ac6
BD
12976
12977 if Nkind (Current_Value (Ent)) not in N_Subexpr then
12978 Set_Current_Value (Ent, Cnode);
12979 end if;
12980 end;
12981 end if;
12982 end Set_Entity_Current_Value;
12983
12984 ----------------------------------
12985 -- Set_Expression_Current_Value --
12986 ----------------------------------
12987
12988 procedure Set_Expression_Current_Value (N : Node_Id) is
12989 Cond : Node_Id;
12990
12991 begin
12992 Cond := N;
12993
12994 -- Loop to deal with (ignore for now) any NOT operators present. The
12995 -- presence of NOT operators will be handled properly when we call
12996 -- Get_Current_Value_Condition.
12997
12998 while Nkind (Cond) = N_Op_Not loop
12999 Cond := Right_Opnd (Cond);
13000 end loop;
13001
13002 -- For an AND or AND THEN, recursively process operands
13003
13004 if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then
13005 Set_Expression_Current_Value (Left_Opnd (Cond));
13006 Set_Expression_Current_Value (Right_Opnd (Cond));
13007 return;
13008 end if;
13009
13010 -- Check possible relational operator
13011
13012 if Nkind (Cond) in N_Op_Compare then
13013 if Compile_Time_Known_Value (Right_Opnd (Cond)) then
13014 Set_Entity_Current_Value (Left_Opnd (Cond));
13015 elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then
13016 Set_Entity_Current_Value (Right_Opnd (Cond));
13017 end if;
13018
4a08c95c
AC
13019 elsif Nkind (Cond) in N_Type_Conversion
13020 | N_Qualified_Expression
13021 | N_Expression_With_Actions
064f4527
TQ
13022 then
13023 Set_Expression_Current_Value (Expression (Cond));
13024
13025 -- Check possible boolean variable reference
05350ac6
BD
13026
13027 else
13028 Set_Entity_Current_Value (Cond);
13029 end if;
13030 end Set_Expression_Current_Value;
13031
13032 -- Start of processing for Set_Current_Value_Condition
13033
13034 begin
13035 Set_Expression_Current_Value (Condition (Cnode));
13036 end Set_Current_Value_Condition;
13037
70482933
RK
13038 --------------------------
13039 -- Set_Elaboration_Flag --
13040 --------------------------
13041
13042 procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is
13043 Loc : constant Source_Ptr := Sloc (N);
fbf5a39b 13044 Ent : constant Entity_Id := Elaboration_Entity (Spec_Id);
70482933
RK
13045 Asn : Node_Id;
13046
13047 begin
fbf5a39b 13048 if Present (Ent) then
70482933
RK
13049
13050 -- Nothing to do if at the compilation unit level, because in this
13051 -- case the flag is set by the binder generated elaboration routine.
13052
13053 if Nkind (Parent (N)) = N_Compilation_Unit then
13054 null;
13055
13056 -- Here we do need to generate an assignment statement
13057
13058 else
13059 Check_Restriction (No_Elaboration_Code, N);
8dce7371 13060
70482933
RK
13061 Asn :=
13062 Make_Assignment_Statement (Loc,
fbf5a39b 13063 Name => New_Occurrence_Of (Ent, Loc),
824e9320 13064 Expression => Make_Integer_Literal (Loc, Uint_1));
70482933 13065
8dce7371
PMR
13066 -- Mark the assignment statement as elaboration code. This allows
13067 -- the early call region mechanism (see Sem_Elab) to properly
3f833dc2 13068 -- ignore such assignments even though they are nonpreelaborable
8dce7371
PMR
13069 -- code.
13070
13071 Set_Is_Elaboration_Code (Asn);
13072
70482933
RK
13073 if Nkind (Parent (N)) = N_Subunit then
13074 Insert_After (Corresponding_Stub (Parent (N)), Asn);
13075 else
13076 Insert_After (N, Asn);
13077 end if;
13078
13079 Analyze (Asn);
fbf5a39b 13080
65df5b71
HK
13081 -- Kill current value indication. This is necessary because the
13082 -- tests of this flag are inserted out of sequence and must not
13083 -- pick up bogus indications of the wrong constant value.
fbf5a39b
AC
13084
13085 Set_Current_Value (Ent, Empty);
113a9fb6
AC
13086
13087 -- If the subprogram is in the current declarative part and
13088 -- 'access has been applied to it, generate an elaboration
13089 -- check at the beginning of the declarations of the body.
13090
13091 if Nkind (N) = N_Subprogram_Body
13092 and then Address_Taken (Spec_Id)
13093 and then
4a08c95c 13094 Ekind (Scope (Spec_Id)) in E_Block | E_Procedure | E_Function
113a9fb6
AC
13095 then
13096 declare
13097 Loc : constant Source_Ptr := Sloc (N);
13098 Decls : constant List_Id := Declarations (N);
13099 Chk : Node_Id;
13100
13101 begin
13102 -- No need to generate this check if first entry in the
13103 -- declaration list is a raise of Program_Error now.
13104
13105 if Present (Decls)
13106 and then Nkind (First (Decls)) = N_Raise_Program_Error
13107 then
13108 return;
13109 end if;
13110
13111 -- Otherwise generate the check
13112
13113 Chk :=
13114 Make_Raise_Program_Error (Loc,
13115 Condition =>
13116 Make_Op_Eq (Loc,
13117 Left_Opnd => New_Occurrence_Of (Ent, Loc),
13118 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)),
13119 Reason => PE_Access_Before_Elaboration);
13120
13121 if No (Decls) then
13122 Set_Declarations (N, New_List (Chk));
13123 else
13124 Prepend (Chk, Decls);
13125 end if;
13126
13127 Analyze (Chk);
13128 end;
13129 end if;
70482933
RK
13130 end if;
13131 end if;
13132 end Set_Elaboration_Flag;
13133
59e54267
ES
13134 ----------------------------
13135 -- Set_Renamed_Subprogram --
13136 ----------------------------
13137
13138 procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is
13139 begin
13140 -- If input node is an identifier, we can just reset it
13141
13142 if Nkind (N) = N_Identifier then
13143 Set_Chars (N, Chars (E));
13144 Set_Entity (N, E);
13145
13146 -- Otherwise we have to do a rewrite, preserving Comes_From_Source
13147
13148 else
13149 declare
13150 CS : constant Boolean := Comes_From_Source (N);
13151 begin
7675ad4f 13152 Rewrite (N, Make_Identifier (Sloc (N), Chars (E)));
59e54267
ES
13153 Set_Entity (N, E);
13154 Set_Comes_From_Source (N, CS);
13155 Set_Analyzed (N, True);
13156 end;
13157 end if;
13158 end Set_Renamed_Subprogram;
13159
adb252d8
AC
13160 ----------------------
13161 -- Side_Effect_Free --
13162 ----------------------
13163
13164 function Side_Effect_Free
13165 (N : Node_Id;
13166 Name_Req : Boolean := False;
13167 Variable_Ref : Boolean := False) return Boolean
13168 is
e7cff5af
RD
13169 Typ : constant Entity_Id := Etype (N);
13170 -- Result type of the expression
13171
adb252d8
AC
13172 function Safe_Prefixed_Reference (N : Node_Id) return Boolean;
13173 -- The argument N is a construct where the Prefix is dereferenced if it
13174 -- is an access type and the result is a variable. The call returns True
13175 -- if the construct is side effect free (not considering side effects in
13176 -- other than the prefix which are to be tested by the caller).
13177
13178 function Within_In_Parameter (N : Node_Id) return Boolean;
13179 -- Determines if N is a subcomponent of a composite in-parameter. If so,
13180 -- N is not side-effect free when the actual is global and modifiable
13181 -- indirectly from within a subprogram, because it may be passed by
13182 -- reference. The front-end must be conservative here and assume that
13183 -- this may happen with any array or record type. On the other hand, we
13184 -- cannot create temporaries for all expressions for which this
13185 -- condition is true, for various reasons that might require clearing up
13186 -- ??? For example, discriminant references that appear out of place, or
13187 -- spurious type errors with class-wide expressions. As a result, we
13188 -- limit the transformation to loop bounds, which is so far the only
13189 -- case that requires it.
13190
13191 -----------------------------
13192 -- Safe_Prefixed_Reference --
13193 -----------------------------
13194
13195 function Safe_Prefixed_Reference (N : Node_Id) return Boolean is
13196 begin
13197 -- If prefix is not side effect free, definitely not safe
13198
13199 if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then
13200 return False;
13201
13202 -- If the prefix is of an access type that is not access-to-constant,
13203 -- then this construct is a variable reference, which means it is to
13204 -- be considered to have side effects if Variable_Ref is set True.
13205
13206 elsif Is_Access_Type (Etype (Prefix (N)))
13207 and then not Is_Access_Constant (Etype (Prefix (N)))
13208 and then Variable_Ref
13209 then
13210 -- Exception is a prefix that is the result of a previous removal
92b751fd 13211 -- of side effects.
adb252d8
AC
13212
13213 return Is_Entity_Name (Prefix (N))
13214 and then not Comes_From_Source (Prefix (N))
13215 and then Ekind (Entity (Prefix (N))) = E_Constant
13216 and then Is_Internal_Name (Chars (Entity (Prefix (N))));
13217
13218 -- If the prefix is an explicit dereference then this construct is a
13219 -- variable reference, which means it is to be considered to have
13220 -- side effects if Variable_Ref is True.
13221
13222 -- We do NOT exclude dereferences of access-to-constant types because
13223 -- we handle them as constant view of variables.
13224
13225 elsif Nkind (Prefix (N)) = N_Explicit_Dereference
13226 and then Variable_Ref
13227 then
13228 return False;
13229
13230 -- Note: The following test is the simplest way of solving a complex
13231 -- problem uncovered by the following test (Side effect on loop bound
13232 -- that is a subcomponent of a global variable:
13233
13234 -- with Text_Io; use Text_Io;
13235 -- procedure Tloop is
13236 -- type X is
13237 -- record
13238 -- V : Natural := 4;
13239 -- S : String (1..5) := (others => 'a');
13240 -- end record;
13241 -- X1 : X;
13242
13243 -- procedure Modi;
13244
13245 -- generic
13246 -- with procedure Action;
13247 -- procedure Loop_G (Arg : X; Msg : String)
13248
13249 -- procedure Loop_G (Arg : X; Msg : String) is
13250 -- begin
13251 -- Put_Line ("begin loop_g " & Msg & " will loop till: "
13252 -- & Natural'Image (Arg.V));
13253 -- for Index in 1 .. Arg.V loop
13254 -- Text_Io.Put_Line
13255 -- (Natural'Image (Index) & " " & Arg.S (Index));
13256 -- if Index > 2 then
13257 -- Modi;
13258 -- end if;
13259 -- end loop;
13260 -- Put_Line ("end loop_g " & Msg);
13261 -- end;
13262
13263 -- procedure Loop1 is new Loop_G (Modi);
13264 -- procedure Modi is
13265 -- begin
13266 -- X1.V := 1;
13267 -- Loop1 (X1, "from modi");
13268 -- end;
13269 --
13270 -- begin
13271 -- Loop1 (X1, "initial");
13272 -- end;
13273
13274 -- The output of the above program should be:
13275
13276 -- begin loop_g initial will loop till: 4
13277 -- 1 a
13278 -- 2 a
13279 -- 3 a
13280 -- begin loop_g from modi will loop till: 1
13281 -- 1 a
13282 -- end loop_g from modi
13283 -- 4 a
13284 -- begin loop_g from modi will loop till: 1
13285 -- 1 a
13286 -- end loop_g from modi
13287 -- end loop_g initial
13288
13289 -- If a loop bound is a subcomponent of a global variable, a
13290 -- modification of that variable within the loop may incorrectly
13291 -- affect the execution of the loop.
13292
13293 elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification
13294 and then Within_In_Parameter (Prefix (N))
13295 and then Variable_Ref
13296 then
13297 return False;
13298
13299 -- All other cases are side effect free
13300
13301 else
13302 return True;
13303 end if;
13304 end Safe_Prefixed_Reference;
13305
13306 -------------------------
13307 -- Within_In_Parameter --
13308 -------------------------
13309
13310 function Within_In_Parameter (N : Node_Id) return Boolean is
13311 begin
13312 if not Comes_From_Source (N) then
13313 return False;
13314
13315 elsif Is_Entity_Name (N) then
13316 return Ekind (Entity (N)) = E_In_Parameter;
13317
4a08c95c 13318 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then
adb252d8
AC
13319 return Within_In_Parameter (Prefix (N));
13320
13321 else
13322 return False;
13323 end if;
13324 end Within_In_Parameter;
13325
13326 -- Start of processing for Side_Effect_Free
13327
13328 begin
bb012790
AC
13329 -- If volatile reference, always consider it to have side effects
13330
13331 if Is_Volatile_Reference (N) then
13332 return False;
13333 end if;
13334
adb252d8
AC
13335 -- Note on checks that could raise Constraint_Error. Strictly, if we
13336 -- take advantage of 11.6, these checks do not count as side effects.
13337 -- However, we would prefer to consider that they are side effects,
bb072d1c 13338 -- since the back end CSE does not work very well on expressions which
adb252d8
AC
13339 -- can raise Constraint_Error. On the other hand if we don't consider
13340 -- them to be side effect free, then we get some awkward expansions
13341 -- in -gnato mode, resulting in code insertions at a point where we
13342 -- do not have a clear model for performing the insertions.
13343
13344 -- Special handling for entity names
13345
13346 if Is_Entity_Name (N) then
13347
bb012790
AC
13348 -- A type reference is always side effect free
13349
13350 if Is_Type (Entity (N)) then
13351 return True;
13352
adb252d8
AC
13353 -- Variables are considered to be a side effect if Variable_Ref
13354 -- is set or if we have a volatile reference and Name_Req is off.
13355 -- If Name_Req is True then we can't help returning a name which
13356 -- effectively allows multiple references in any case.
13357
bb012790 13358 elsif Is_Variable (N, Use_Original_Node => False) then
adb252d8
AC
13359 return not Variable_Ref
13360 and then (not Is_Volatile_Reference (N) or else Name_Req);
13361
13362 -- Any other entity (e.g. a subtype name) is definitely side
13363 -- effect free.
13364
13365 else
13366 return True;
13367 end if;
13368
13369 -- A value known at compile time is always side effect free
13370
13371 elsif Compile_Time_Known_Value (N) then
13372 return True;
13373
13374 -- A variable renaming is not side-effect free, because the renaming
13375 -- will function like a macro in the front-end in some cases, and an
13376 -- assignment can modify the component designated by N, so we need to
13377 -- create a temporary for it.
13378
13379 -- The guard testing for Entity being present is needed at least in
13380 -- the case of rewritten predicate expressions, and may well also be
13381 -- appropriate elsewhere. Obviously we can't go testing the entity
13382 -- field if it does not exist, so it's reasonable to say that this is
13383 -- not the renaming case if it does not exist.
13384
13385 elsif Is_Entity_Name (Original_Node (N))
13386 and then Present (Entity (Original_Node (N)))
13387 and then Is_Renaming_Of_Object (Entity (Original_Node (N)))
13388 and then Ekind (Entity (Original_Node (N))) /= E_Constant
13389 then
13390 declare
13391 RO : constant Node_Id :=
13392 Renamed_Object (Entity (Original_Node (N)));
13393
13394 begin
13395 -- If the renamed object is an indexed component, or an
13396 -- explicit dereference, then the designated object could
13397 -- be modified by an assignment.
13398
4a08c95c 13399 if Nkind (RO) in N_Indexed_Component | N_Explicit_Dereference then
adb252d8
AC
13400 return False;
13401
13402 -- A selected component must have a safe prefix
13403
13404 elsif Nkind (RO) = N_Selected_Component then
13405 return Safe_Prefixed_Reference (RO);
13406
13407 -- In all other cases, designated object cannot be changed so
13408 -- we are side effect free.
13409
13410 else
13411 return True;
13412 end if;
13413 end;
13414
13415 -- Remove_Side_Effects generates an object renaming declaration to
13416 -- capture the expression of a class-wide expression. In VM targets
13417 -- the frontend performs no expansion for dispatching calls to
13418 -- class- wide types since they are handled by the VM. Hence, we must
13419 -- locate here if this node corresponds to a previous invocation of
13420 -- Remove_Side_Effects to avoid a never ending loop in the frontend.
13421
535a8637 13422 elsif not Tagged_Type_Expansion
f145ece7
AC
13423 and then not Comes_From_Source (N)
13424 and then Nkind (Parent (N)) = N_Object_Renaming_Declaration
13425 and then Is_Class_Wide_Type (Typ)
adb252d8
AC
13426 then
13427 return True;
6905a049
AC
13428
13429 -- Generating C the type conversion of an access to constrained array
13430 -- type into an access to unconstrained array type involves initializing
13431 -- a fat pointer and the expression cannot be assumed to be free of side
13432 -- effects since it must referenced several times to compute its bounds.
13433
c63a2ad6 13434 elsif Modify_Tree_For_C
6905a049
AC
13435 and then Nkind (N) = N_Type_Conversion
13436 and then Is_Access_Type (Typ)
13437 and then Is_Array_Type (Designated_Type (Typ))
13438 and then not Is_Constrained (Designated_Type (Typ))
13439 then
13440 return False;
adb252d8
AC
13441 end if;
13442
13443 -- For other than entity names and compile time known values,
13444 -- check the node kind for special processing.
13445
13446 case Nkind (N) is
13447
cf9e3829
EB
13448 -- An attribute reference is side-effect free if its expressions
13449 -- are side-effect free and its prefix is side-effect free or is
13450 -- an entity reference.
adb252d8
AC
13451
13452 when N_Attribute_Reference =>
cf9e3829
EB
13453 return Side_Effect_Free_Attribute (Attribute_Name (N))
13454 and then
13455 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
13456 and then
13457 (Is_Entity_Name (Prefix (N))
13458 or else
13459 Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref));
adb252d8
AC
13460
13461 -- A binary operator is side effect free if and both operands are
13462 -- side effect free. For this purpose binary operators include
13463 -- membership tests and short circuit forms.
13464
d8f43ee6
HK
13465 when N_Binary_Op
13466 | N_Membership_Test
13467 | N_Short_Circuit
13468 =>
adb252d8
AC
13469 return Side_Effect_Free (Left_Opnd (N), Name_Req, Variable_Ref)
13470 and then
13471 Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
13472
13473 -- An explicit dereference is side effect free only if it is
13474 -- a side effect free prefixed reference.
13475
13476 when N_Explicit_Dereference =>
13477 return Safe_Prefixed_Reference (N);
13478
13479 -- An expression with action is side effect free if its expression
13480 -- is side effect free and it has no actions.
13481
13482 when N_Expression_With_Actions =>
d8f43ee6
HK
13483 return
13484 Is_Empty_List (Actions (N))
13485 and then Side_Effect_Free
13486 (Expression (N), Name_Req, Variable_Ref);
adb252d8
AC
13487
13488 -- A call to _rep_to_pos is side effect free, since we generate
13489 -- this pure function call ourselves. Moreover it is critically
13490 -- important to make this exception, since otherwise we can have
13491 -- discriminants in array components which don't look side effect
13492 -- free in the case of an array whose index type is an enumeration
13493 -- type with an enumeration rep clause.
13494
13495 -- All other function calls are not side effect free
13496
13497 when N_Function_Call =>
d8f43ee6
HK
13498 return
13499 Nkind (Name (N)) = N_Identifier
13500 and then Is_TSS (Name (N), TSS_Rep_To_Pos)
13501 and then Side_Effect_Free
13502 (First (Parameter_Associations (N)),
13503 Name_Req, Variable_Ref);
adb252d8 13504
e7cff5af
RD
13505 -- An IF expression is side effect free if it's of a scalar type, and
13506 -- all its components are all side effect free (conditions and then
13507 -- actions and else actions). We restrict to scalar types, since it
13508 -- is annoying to deal with things like (if A then B else C)'First
13509 -- where the type involved is a string type.
a767d69b 13510
e7cff5af 13511 when N_If_Expression =>
d8f43ee6
HK
13512 return
13513 Is_Scalar_Type (Typ)
13514 and then Side_Effect_Free
13515 (Expressions (N), Name_Req, Variable_Ref);
a767d69b 13516
adb252d8
AC
13517 -- An indexed component is side effect free if it is a side
13518 -- effect free prefixed reference and all the indexing
13519 -- expressions are side effect free.
13520
13521 when N_Indexed_Component =>
d8f43ee6
HK
13522 return
13523 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref)
13524 and then Safe_Prefixed_Reference (N);
adb252d8 13525
304757d2
AC
13526 -- A type qualification, type conversion, or unchecked expression is
13527 -- side effect free if the expression is side effect free.
adb252d8 13528
304757d2
AC
13529 when N_Qualified_Expression
13530 | N_Type_Conversion
13531 | N_Unchecked_Expression
13532 =>
adb252d8
AC
13533 return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref);
13534
13535 -- A selected component is side effect free only if it is a side
22e89283 13536 -- effect free prefixed reference.
adb252d8
AC
13537
13538 when N_Selected_Component =>
22e89283 13539 return Safe_Prefixed_Reference (N);
adb252d8
AC
13540
13541 -- A range is side effect free if the bounds are side effect free
13542
13543 when N_Range =>
13544 return Side_Effect_Free (Low_Bound (N), Name_Req, Variable_Ref)
c5c780e6 13545 and then
adb252d8
AC
13546 Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref);
13547
13548 -- A slice is side effect free if it is a side effect free
13549 -- prefixed reference and the bounds are side effect free.
13550
13551 when N_Slice =>
d8f43ee6
HK
13552 return
13553 Side_Effect_Free (Discrete_Range (N), Name_Req, Variable_Ref)
13554 and then Safe_Prefixed_Reference (N);
adb252d8 13555
adb252d8
AC
13556 -- A unary operator is side effect free if the operand
13557 -- is side effect free.
13558
13559 when N_Unary_Op =>
13560 return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref);
13561
13562 -- An unchecked type conversion is side effect free only if it
13563 -- is safe and its argument is side effect free.
13564
13565 when N_Unchecked_Type_Conversion =>
d8f43ee6
HK
13566 return
13567 Safe_Unchecked_Type_Conversion (N)
13568 and then Side_Effect_Free
13569 (Expression (N), Name_Req, Variable_Ref);
adb252d8 13570
adb252d8
AC
13571 -- A literal is side effect free
13572
d8f43ee6
HK
13573 when N_Character_Literal
13574 | N_Integer_Literal
13575 | N_Real_Literal
13576 | N_String_Literal
13577 =>
adb252d8
AC
13578 return True;
13579
c4609e75
AC
13580 -- An aggregate is side effect free if all its values are compile
13581 -- time known.
13582
13583 when N_Aggregate =>
13584 return Compile_Time_Known_Aggregate (N);
13585
adb252d8
AC
13586 -- We consider that anything else has side effects. This is a bit
13587 -- crude, but we are pretty close for most common cases, and we
13588 -- are certainly correct (i.e. we never return True when the
13589 -- answer should be False).
13590
13591 when others =>
13592 return False;
13593 end case;
13594 end Side_Effect_Free;
13595
13596 -- A list is side effect free if all elements of the list are side
13597 -- effect free.
13598
13599 function Side_Effect_Free
13600 (L : List_Id;
13601 Name_Req : Boolean := False;
13602 Variable_Ref : Boolean := False) return Boolean
13603 is
13604 N : Node_Id;
13605
13606 begin
13607 if L = No_List or else L = Error_List then
13608 return True;
13609
13610 else
13611 N := First (L);
13612 while Present (N) loop
13613 if not Side_Effect_Free (N, Name_Req, Variable_Ref) then
13614 return False;
13615 else
13616 Next (N);
13617 end if;
13618 end loop;
13619
13620 return True;
13621 end if;
13622 end Side_Effect_Free;
13623
cf9e3829
EB
13624 --------------------------------
13625 -- Side_Effect_Free_Attribute --
13626 --------------------------------
13627
13628 function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean is
13629 begin
13630 case Name is
13631 when Name_Input =>
13632 return False;
13633
13634 when Name_Image
13635 | Name_Img
13636 | Name_Wide_Image
13637 | Name_Wide_Wide_Image
13638 =>
13639 -- CodePeer doesn't want to see replicated copies of 'Image calls
13640
13641 return not CodePeer_Mode;
13642
13643 when others =>
13644 return True;
13645 end case;
13646 end Side_Effect_Free_Attribute;
13647
65df5b71
HK
13648 ----------------------------------
13649 -- Silly_Boolean_Array_Not_Test --
13650 ----------------------------------
13651
13652 -- This procedure implements an odd and silly test. We explicitly check
13653 -- for the case where the 'First of the component type is equal to the
13654 -- 'Last of this component type, and if this is the case, we make sure
13655 -- that constraint error is raised. The reason is that the NOT is bound
13656 -- to cause CE in this case, and we will not otherwise catch it.
13657
b3b9865d
AC
13658 -- No such check is required for AND and OR, since for both these cases
13659 -- False op False = False, and True op True = True. For the XOR case,
13660 -- see Silly_Boolean_Array_Xor_Test.
13661
273adcdf
AC
13662 -- Believe it or not, this was reported as a bug. Note that nearly always,
13663 -- the test will evaluate statically to False, so the code will be
13664 -- statically removed, and no extra overhead caused.
65df5b71
HK
13665
13666 procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is
13667 Loc : constant Source_Ptr := Sloc (N);
13668 CT : constant Entity_Id := Component_Type (T);
13669
13670 begin
b3b9865d
AC
13671 -- The check we install is
13672
13673 -- constraint_error when
13674 -- component_type'first = component_type'last
13675 -- and then array_type'Length /= 0)
13676
13677 -- We need the last guard because we don't want to raise CE for empty
13678 -- arrays since no out of range values result. (Empty arrays with a
13679 -- component type of True .. True -- very useful -- even the ACATS
a90bd866 13680 -- does not test that marginal case).
b3b9865d 13681
65df5b71
HK
13682 Insert_Action (N,
13683 Make_Raise_Constraint_Error (Loc,
13684 Condition =>
b3b9865d 13685 Make_And_Then (Loc,
65df5b71 13686 Left_Opnd =>
b3b9865d
AC
13687 Make_Op_Eq (Loc,
13688 Left_Opnd =>
13689 Make_Attribute_Reference (Loc,
13690 Prefix => New_Occurrence_Of (CT, Loc),
13691 Attribute_Name => Name_First),
13692
13693 Right_Opnd =>
13694 Make_Attribute_Reference (Loc,
13695 Prefix => New_Occurrence_Of (CT, Loc),
13696 Attribute_Name => Name_Last)),
13697
13698 Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))),
65df5b71
HK
13699 Reason => CE_Range_Check_Failed));
13700 end Silly_Boolean_Array_Not_Test;
13701
13702 ----------------------------------
13703 -- Silly_Boolean_Array_Xor_Test --
13704 ----------------------------------
13705
13706 -- This procedure implements an odd and silly test. We explicitly check
13707 -- for the XOR case where the component type is True .. True, since this
13708 -- will raise constraint error. A special check is required since CE
f17889b3 13709 -- will not be generated otherwise (cf Expand_Packed_Not).
65df5b71
HK
13710
13711 -- No such check is required for AND and OR, since for both these cases
b3b9865d
AC
13712 -- False op False = False, and True op True = True, and no check is
13713 -- required for the case of False .. False, since False xor False = False.
13714 -- See also Silly_Boolean_Array_Not_Test
65df5b71 13715
076bbec1 13716 procedure Silly_Boolean_Array_Xor_Test
89beb653
HK
13717 (N : Node_Id;
13718 R : Node_Id;
13719 T : Entity_Id)
13720 is
65df5b71
HK
13721 Loc : constant Source_Ptr := Sloc (N);
13722 CT : constant Entity_Id := Component_Type (T);
65df5b71
HK
13723
13724 begin
f17889b3
RD
13725 -- The check we install is
13726
13727 -- constraint_error when
13728 -- Boolean (component_type'First)
13729 -- and then Boolean (component_type'Last)
13730 -- and then array_type'Length /= 0)
13731
13732 -- We need the last guard because we don't want to raise CE for empty
13733 -- arrays since no out of range values result (Empty arrays with a
13734 -- component type of True .. True -- very useful -- even the ACATS
a90bd866 13735 -- does not test that marginal case).
f17889b3 13736
65df5b71
HK
13737 Insert_Action (N,
13738 Make_Raise_Constraint_Error (Loc,
13739 Condition =>
f17889b3 13740 Make_And_Then (Loc,
89beb653 13741 Left_Opnd =>
f17889b3 13742 Make_And_Then (Loc,
89beb653 13743 Left_Opnd =>
f17889b3
RD
13744 Convert_To (Standard_Boolean,
13745 Make_Attribute_Reference (Loc,
13746 Prefix => New_Occurrence_Of (CT, Loc),
13747 Attribute_Name => Name_First)),
65df5b71
HK
13748
13749 Right_Opnd =>
f17889b3
RD
13750 Convert_To (Standard_Boolean,
13751 Make_Attribute_Reference (Loc,
13752 Prefix => New_Occurrence_Of (CT, Loc),
13753 Attribute_Name => Name_Last))),
65df5b71 13754
076bbec1 13755 Right_Opnd => Make_Non_Empty_Check (Loc, R)),
89beb653 13756 Reason => CE_Range_Check_Failed));
65df5b71
HK
13757 end Silly_Boolean_Array_Xor_Test;
13758
c7c7dd3a
EB
13759 ----------------------------
13760 -- Small_Integer_Type_For --
13761 ----------------------------
13762
13763 function Small_Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id
13764 is
13765 begin
13766 pragma Assert (S <= System_Max_Integer_Size);
13767
13768 if S <= Standard_Short_Short_Integer_Size then
13769 if Uns then
13770 return Standard_Short_Short_Unsigned;
13771 else
13772 return Standard_Short_Short_Integer;
13773 end if;
13774
13775 elsif S <= Standard_Short_Integer_Size then
13776 if Uns then
13777 return Standard_Short_Unsigned;
13778 else
13779 return Standard_Short_Integer;
13780 end if;
13781
13782 elsif S <= Standard_Integer_Size then
13783 if Uns then
13784 return Standard_Unsigned;
13785 else
13786 return Standard_Integer;
13787 end if;
13788
13789 elsif S <= Standard_Long_Integer_Size then
13790 if Uns then
13791 return Standard_Long_Unsigned;
13792 else
13793 return Standard_Long_Integer;
13794 end if;
13795
13796 elsif S <= Standard_Long_Long_Integer_Size then
13797 if Uns then
13798 return Standard_Long_Long_Unsigned;
13799 else
13800 return Standard_Long_Long_Integer;
13801 end if;
13802
a5476382
EB
13803 elsif S <= Standard_Long_Long_Long_Integer_Size then
13804 if Uns then
13805 return Standard_Long_Long_Long_Unsigned;
13806 else
13807 return Standard_Long_Long_Long_Integer;
13808 end if;
13809
c7c7dd3a
EB
13810 else
13811 raise Program_Error;
13812 end if;
13813 end Small_Integer_Type_For;
13814
b619c88e
AC
13815 -------------------
13816 -- Type_Map_Hash --
13817 -------------------
13818
13819 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header is
13820 begin
13821 return Type_Map_Header (Id mod Type_Map_Size);
13822 end Type_Map_Hash;
13823
91b1417d
AC
13824 ------------------------------------------
13825 -- Type_May_Have_Bit_Aligned_Components --
13826 ------------------------------------------
13827
13828 function Type_May_Have_Bit_Aligned_Components
13829 (Typ : Entity_Id) return Boolean
13830 is
13831 begin
13832 -- Array type, check component type
13833
13834 if Is_Array_Type (Typ) then
13835 return
13836 Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
13837
13838 -- Record type, check components
13839
13840 elsif Is_Record_Type (Typ) then
13841 declare
13842 E : Entity_Id;
13843
13844 begin
dee4682a 13845 E := First_Component_Or_Discriminant (Typ);
91b1417d 13846 while Present (E) loop
fba9fcae
EB
13847 -- This is the crucial test: if the component itself causes
13848 -- trouble, then we can stop and return True.
13849
13850 if Component_May_Be_Bit_Aligned (E) then
13851 return True;
13852 end if;
13853
13854 -- Otherwise, we need to test its type, to see if it may
13855 -- itself contain a troublesome component.
13856
13857 if Type_May_Have_Bit_Aligned_Components (Etype (E)) then
dee4682a 13858 return True;
91b1417d
AC
13859 end if;
13860
dee4682a 13861 Next_Component_Or_Discriminant (E);
91b1417d
AC
13862 end loop;
13863
13864 return False;
13865 end;
13866
13867 -- Type other than array or record is always OK
13868
13869 else
13870 return False;
13871 end if;
13872 end Type_May_Have_Bit_Aligned_Components;
13873
f63d601b
HK
13874 -------------------------------
13875 -- Update_Primitives_Mapping --
13876 -------------------------------
13877
13878 procedure Update_Primitives_Mapping
13879 (Inher_Id : Entity_Id;
13880 Subp_Id : Entity_Id)
13881 is
13882 begin
b619c88e
AC
13883 Map_Types
13884 (Parent_Type => Find_Dispatching_Type (Inher_Id),
13885 Derived_Type => Find_Dispatching_Type (Subp_Id));
f63d601b
HK
13886 end Update_Primitives_Mapping;
13887
4c7e0990
AC
13888 ----------------------------------
13889 -- Within_Case_Or_If_Expression --
13890 ----------------------------------
13891
13892 function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is
13893 Par : Node_Id;
13894
13895 begin
b2c28399
AC
13896 -- Locate an enclosing case or if expression. Note that these constructs
13897 -- can be expanded into Expression_With_Actions, hence the test of the
13898 -- original node.
4c7e0990 13899
b2c28399 13900 Par := Parent (N);
4c7e0990 13901 while Present (Par) loop
4a08c95c 13902 if Nkind (Original_Node (Par)) in N_Case_Expression | N_If_Expression
4c7e0990
AC
13903 then
13904 return True;
13905
13906 -- Prevent the search from going too far
13907
a7e68e7f 13908 elsif Is_Body_Or_Package_Declaration (Par) then
4c7e0990
AC
13909 return False;
13910 end if;
13911
13912 Par := Parent (Par);
13913 end loop;
13914
13915 return False;
13916 end Within_Case_Or_If_Expression;
13917
152f64c2
AC
13918 ------------------------------
13919 -- Predicate_Check_In_Scope --
13920 ------------------------------
8e1e62e3 13921
152f64c2 13922 function Predicate_Check_In_Scope (N : Node_Id) return Boolean is
8e1e62e3
AC
13923 S : Entity_Id;
13924
13925 begin
13926 S := Current_Scope;
13927 while Present (S) and then not Is_Subprogram (S) loop
13928 S := Scope (S);
13929 end loop;
13930
152f64c2
AC
13931 if Present (S) then
13932
13933 -- Predicate checks should only be enabled in init procs for
13934 -- expressions coming from source.
13935
13936 if Is_Init_Proc (S) then
13937 return Comes_From_Source (N);
13938
13939 elsif Get_TSS_Name (S) /= TSS_Null
13940 and then not Is_Predicate_Function (S)
13941 and then not Is_Predicate_Function_M (S)
13942 then
13943 return False;
13944 end if;
13945 end if;
13946
13947 return True;
13948 end Predicate_Check_In_Scope;
8e1e62e3 13949
70482933 13950end Exp_Util;