1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- E X P _ U T I L -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1992-2020, Free Software Foundation, Inc. -- 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- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 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 -- 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. -- 20-- -- 21-- GNAT was originally developed by the GNAT team at New York University. -- 22-- Extensive contributions were provided by Ada Core Technologies Inc. -- 23-- -- 24------------------------------------------------------------------------------ 25 26with Aspects; use Aspects; 27with Atree; use Atree; 28with Casing; use Casing; 29with Checks; use Checks; 30with Debug; use Debug; 31with Einfo; use Einfo; 32with Elists; use Elists; 33with Errout; use Errout; 34with Exp_Aggr; use Exp_Aggr; 35with Exp_Ch6; use Exp_Ch6; 36with Exp_Ch7; use Exp_Ch7; 37with Exp_Ch11; use Exp_Ch11; 38with Ghost; use Ghost; 39with Inline; use Inline; 40with Itypes; use Itypes; 41with Lib; use Lib; 42with Nlists; use Nlists; 43with Nmake; use Nmake; 44with Opt; use Opt; 45with Restrict; use Restrict; 46with Rident; use Rident; 47with Sem; use Sem; 48with Sem_Aux; use Sem_Aux; 49with Sem_Ch3; use Sem_Ch3; 50with Sem_Ch6; use Sem_Ch6; 51with Sem_Ch8; use Sem_Ch8; 52with Sem_Ch12; use Sem_Ch12; 53with Sem_Ch13; use Sem_Ch13; 54with Sem_Disp; use Sem_Disp; 55with Sem_Elab; use Sem_Elab; 56with Sem_Eval; use Sem_Eval; 57with Sem_Res; use Sem_Res; 58with Sem_Type; use Sem_Type; 59with Sem_Util; use Sem_Util; 60with Snames; use Snames; 61with Stand; use Stand; 62with Stringt; use Stringt; 63with Tbuild; use Tbuild; 64with Ttypes; use Ttypes; 65with Validsw; use Validsw; 66 67with GNAT.HTable; 68package body Exp_Util is 69 70 --------------------------------------------------------- 71 -- Handling of inherited class-wide pre/postconditions -- 72 --------------------------------------------------------- 73 74 -- Following AI12-0113, the expression for a class-wide condition is 75 -- transformed for a subprogram that inherits it, by replacing calls 76 -- to primitive operations of the original controlling type into the 77 -- corresponding overriding operations of the derived type. The following 78 -- hash table manages this mapping, and is expanded on demand whenever 79 -- such inherited expression needs to be constructed. 80 81 -- The mapping is also used to check whether an inherited operation has 82 -- a condition that depends on overridden operations. For such an 83 -- operation we must create a wrapper that is then treated as a normal 84 -- overriding. In SPARK mode such operations are illegal. 85 86 -- For a given root type there may be several type extensions with their 87 -- own overriding operations, so at various times a given operation of 88 -- the root will be mapped into different overridings. The root type is 89 -- also mapped into the current type extension to indicate that its 90 -- operations are mapped into the overriding operations of that current 91 -- type extension. 92 93 -- The contents of the map are as follows: 94 95 -- Key Value 96 97 -- Discriminant (Entity_Id) Discriminant (Entity_Id) 98 -- Discriminant (Entity_Id) Non-discriminant name (Entity_Id) 99 -- Discriminant (Entity_Id) Expression (Node_Id) 100 -- Primitive subprogram (Entity_Id) Primitive subprogram (Entity_Id) 101 -- Type (Entity_Id) Type (Entity_Id) 102 103 Type_Map_Size : constant := 511; 104 105 subtype Type_Map_Header is Integer range 0 .. Type_Map_Size - 1; 106 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header; 107 108 package Type_Map is new GNAT.HTable.Simple_HTable 109 (Header_Num => Type_Map_Header, 110 Key => Entity_Id, 111 Element => Node_Or_Entity_Id, 112 No_element => Empty, 113 Hash => Type_Map_Hash, 114 Equal => "="); 115 116 ----------------------- 117 -- Local Subprograms -- 118 ----------------------- 119 120 function Build_Task_Array_Image 121 (Loc : Source_Ptr; 122 Id_Ref : Node_Id; 123 A_Type : Entity_Id; 124 Dyn : Boolean := False) return Node_Id; 125 -- Build function to generate the image string for a task that is an array 126 -- component, concatenating the images of each index. To avoid storage 127 -- leaks, the string is built with successive slice assignments. The flag 128 -- Dyn indicates whether this is called for the initialization procedure of 129 -- an array of tasks, or for the name of a dynamically created task that is 130 -- assigned to an indexed component. 131 132 function Build_Task_Image_Function 133 (Loc : Source_Ptr; 134 Decls : List_Id; 135 Stats : List_Id; 136 Res : Entity_Id) return Node_Id; 137 -- Common processing for Task_Array_Image and Task_Record_Image. Build 138 -- function body that computes image. 139 140 procedure Build_Task_Image_Prefix 141 (Loc : Source_Ptr; 142 Len : out Entity_Id; 143 Res : out Entity_Id; 144 Pos : out Entity_Id; 145 Prefix : Entity_Id; 146 Sum : Node_Id; 147 Decls : List_Id; 148 Stats : List_Id); 149 -- Common processing for Task_Array_Image and Task_Record_Image. Create 150 -- local variables and assign prefix of name to result string. 151 152 function Build_Task_Record_Image 153 (Loc : Source_Ptr; 154 Id_Ref : Node_Id; 155 Dyn : Boolean := False) return Node_Id; 156 -- Build function to generate the image string for a task that is a record 157 -- component. Concatenate name of variable with that of selector. The flag 158 -- Dyn indicates whether this is called for the initialization procedure of 159 -- record with task components, or for a dynamically created task that is 160 -- assigned to a selected component. 161 162 procedure Evaluate_Slice_Bounds (Slice : Node_Id); 163 -- Force evaluation of bounds of a slice, which may be given by a range 164 -- or by a subtype indication with or without a constraint. 165 166 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean; 167 -- Determine whether pragma Default_Initial_Condition denoted by Prag has 168 -- an assertion expression that should be verified at run time. 169 170 function Is_Uninitialized_Aggregate 171 (Exp : Node_Id; 172 T : Entity_Id) return Boolean; 173 -- Determine whether an array aggregate used in an object declaration 174 -- is uninitialized, when the aggregate is declared with a box and 175 -- the component type has no default value. Such an aggregate can be 176 -- optimized away to prevent the copying of uninitialized data, and 177 -- the bounds of the aggregate can be propagated directly to the 178 -- object declaration. 179 180 function Make_CW_Equivalent_Type 181 (T : Entity_Id; 182 E : Node_Id) return Entity_Id; 183 -- T is a class-wide type entity, E is the initial expression node that 184 -- constrains T in case such as: " X: T := E" or "new T'(E)". This function 185 -- returns the entity of the Equivalent type and inserts on the fly the 186 -- necessary declaration such as: 187 -- 188 -- type anon is record 189 -- _parent : Root_Type (T); constrained with E discriminants (if any) 190 -- Extension : String (1 .. expr to match size of E); 191 -- end record; 192 -- 193 -- This record is compatible with any object of the class of T thanks to 194 -- the first field and has the same size as E thanks to the second. 195 196 function Make_Literal_Range 197 (Loc : Source_Ptr; 198 Literal_Typ : Entity_Id) return Node_Id; 199 -- Produce a Range node whose bounds are: 200 -- Low_Bound (Literal_Type) .. 201 -- Low_Bound (Literal_Type) + (Length (Literal_Typ) - 1) 202 -- this is used for expanding declarations like X : String := "sdfgdfg"; 203 -- 204 -- If the index type of the target array is not integer, we generate: 205 -- Low_Bound (Literal_Type) .. 206 -- Literal_Type'Val 207 -- (Literal_Type'Pos (Low_Bound (Literal_Type)) 208 -- + (Length (Literal_Typ) -1)) 209 210 function Make_Non_Empty_Check 211 (Loc : Source_Ptr; 212 N : Node_Id) return Node_Id; 213 -- Produce a boolean expression checking that the unidimensional array 214 -- node N is not empty. 215 216 function New_Class_Wide_Subtype 217 (CW_Typ : Entity_Id; 218 N : Node_Id) return Entity_Id; 219 -- Create an implicit subtype of CW_Typ attached to node N 220 221 function Requires_Cleanup_Actions 222 (L : List_Id; 223 Lib_Level : Boolean; 224 Nested_Constructs : Boolean) return Boolean; 225 -- Given a list L, determine whether it contains one of the following: 226 -- 227 -- 1) controlled objects 228 -- 2) library-level tagged types 229 -- 230 -- Lib_Level is True when the list comes from a construct at the library 231 -- level, and False otherwise. Nested_Constructs is True when any nested 232 -- packages declared in L must be processed, and False otherwise. 233 234 function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean; 235 -- Return True if the evaluation of the given attribute is considered 236 -- side-effect free, independently of its prefix and expressions. 237 238 ------------------------------------- 239 -- Activate_Atomic_Synchronization -- 240 ------------------------------------- 241 242 procedure Activate_Atomic_Synchronization (N : Node_Id) is 243 Msg_Node : Node_Id; 244 245 begin 246 case Nkind (Parent (N)) is 247 248 -- Check for cases of appearing in the prefix of a construct where we 249 -- don't need atomic synchronization for this kind of usage. 250 251 when 252 -- Nothing to do if we are the prefix of an attribute, since we 253 -- do not want an atomic sync operation for things like 'Size. 254 255 N_Attribute_Reference 256 257 -- The N_Reference node is like an attribute 258 259 | N_Reference 260 261 -- Nothing to do for a reference to a component (or components) 262 -- of a composite object. Only reads and updates of the object 263 -- as a whole require atomic synchronization (RM C.6 (15)). 264 265 | N_Indexed_Component 266 | N_Selected_Component 267 | N_Slice 268 => 269 -- For all the above cases, nothing to do if we are the prefix 270 271 if Prefix (Parent (N)) = N then 272 return; 273 end if; 274 275 when others => 276 null; 277 end case; 278 279 -- Nothing to do for the identifier in an object renaming declaration, 280 -- the renaming itself does not need atomic synchronization. 281 282 if Nkind (Parent (N)) = N_Object_Renaming_Declaration then 283 return; 284 end if; 285 286 -- Go ahead and set the flag 287 288 Set_Atomic_Sync_Required (N); 289 290 -- Generate info message if requested 291 292 if Warn_On_Atomic_Synchronization then 293 case Nkind (N) is 294 when N_Identifier => 295 Msg_Node := N; 296 297 when N_Expanded_Name 298 | N_Selected_Component 299 => 300 Msg_Node := Selector_Name (N); 301 302 when N_Explicit_Dereference 303 | N_Indexed_Component 304 => 305 Msg_Node := Empty; 306 307 when others => 308 pragma Assert (False); 309 return; 310 end case; 311 312 if Present (Msg_Node) then 313 Error_Msg_N 314 ("info: atomic synchronization set for &?N?", Msg_Node); 315 else 316 Error_Msg_N 317 ("info: atomic synchronization set?N?", N); 318 end if; 319 end if; 320 end Activate_Atomic_Synchronization; 321 322 ---------------------- 323 -- Adjust_Condition -- 324 ---------------------- 325 326 procedure Adjust_Condition (N : Node_Id) is 327 begin 328 if No (N) then 329 return; 330 end if; 331 332 declare 333 Loc : constant Source_Ptr := Sloc (N); 334 T : constant Entity_Id := Etype (N); 335 336 begin 337 -- Defend against a call where the argument has no type, or has a 338 -- type that is not Boolean. This can occur because of prior errors. 339 340 if No (T) or else not Is_Boolean_Type (T) then 341 return; 342 end if; 343 344 -- Apply validity checking if needed 345 346 if Validity_Checks_On and Validity_Check_Tests then 347 Ensure_Valid (N); 348 end if; 349 350 -- Immediate return if standard boolean, the most common case, 351 -- where nothing needs to be done. 352 353 if Base_Type (T) = Standard_Boolean then 354 return; 355 end if; 356 357 -- Case of zero/nonzero semantics or nonstandard enumeration 358 -- representation. In each case, we rewrite the node as: 359 360 -- ityp!(N) /= False'Enum_Rep 361 362 -- where ityp is an integer type with large enough size to hold any 363 -- value of type T. 364 365 if Nonzero_Is_True (T) or else Has_Non_Standard_Rep (T) then 366 Rewrite (N, 367 Make_Op_Ne (Loc, 368 Left_Opnd => 369 Unchecked_Convert_To 370 (Integer_Type_For (Esize (T), Uns => False), N), 371 Right_Opnd => 372 Make_Attribute_Reference (Loc, 373 Attribute_Name => Name_Enum_Rep, 374 Prefix => 375 New_Occurrence_Of (First_Literal (T), Loc)))); 376 Analyze_And_Resolve (N, Standard_Boolean); 377 378 else 379 Rewrite (N, Convert_To (Standard_Boolean, N)); 380 Analyze_And_Resolve (N, Standard_Boolean); 381 end if; 382 end; 383 end Adjust_Condition; 384 385 ------------------------ 386 -- Adjust_Result_Type -- 387 ------------------------ 388 389 procedure Adjust_Result_Type (N : Node_Id; T : Entity_Id) is 390 begin 391 -- Ignore call if current type is not Standard.Boolean 392 393 if Etype (N) /= Standard_Boolean then 394 return; 395 end if; 396 397 -- If result is already of correct type, nothing to do. Note that 398 -- this will get the most common case where everything has a type 399 -- of Standard.Boolean. 400 401 if Base_Type (T) = Standard_Boolean then 402 return; 403 404 else 405 declare 406 KP : constant Node_Kind := Nkind (Parent (N)); 407 408 begin 409 -- If result is to be used as a Condition in the syntax, no need 410 -- to convert it back, since if it was changed to Standard.Boolean 411 -- using Adjust_Condition, that is just fine for this usage. 412 413 if KP in N_Raise_xxx_Error or else KP in N_Has_Condition then 414 return; 415 416 -- If result is an operand of another logical operation, no need 417 -- to reset its type, since Standard.Boolean is just fine, and 418 -- such operations always do Adjust_Condition on their operands. 419 420 elsif KP in N_Op_Boolean 421 or else KP in N_Short_Circuit 422 or else KP = N_Op_Not 423 then 424 return; 425 426 -- Otherwise we perform a conversion from the current type, which 427 -- must be Standard.Boolean, to the desired type. Use the base 428 -- type to prevent spurious constraint checks that are extraneous 429 -- to the transformation. The type and its base have the same 430 -- representation, standard or otherwise. 431 432 else 433 Set_Analyzed (N); 434 Rewrite (N, Convert_To (Base_Type (T), N)); 435 Analyze_And_Resolve (N, Base_Type (T)); 436 end if; 437 end; 438 end if; 439 end Adjust_Result_Type; 440 441 -------------------------- 442 -- Append_Freeze_Action -- 443 -------------------------- 444 445 procedure Append_Freeze_Action (T : Entity_Id; N : Node_Id) is 446 Fnode : Node_Id; 447 448 begin 449 Ensure_Freeze_Node (T); 450 Fnode := Freeze_Node (T); 451 452 if No (Actions (Fnode)) then 453 Set_Actions (Fnode, New_List (N)); 454 else 455 Append (N, Actions (Fnode)); 456 end if; 457 458 end Append_Freeze_Action; 459 460 --------------------------- 461 -- Append_Freeze_Actions -- 462 --------------------------- 463 464 procedure Append_Freeze_Actions (T : Entity_Id; L : List_Id) is 465 Fnode : Node_Id; 466 467 begin 468 if No (L) then 469 return; 470 end if; 471 472 Ensure_Freeze_Node (T); 473 Fnode := Freeze_Node (T); 474 475 if No (Actions (Fnode)) then 476 Set_Actions (Fnode, L); 477 else 478 Append_List (L, Actions (Fnode)); 479 end if; 480 end Append_Freeze_Actions; 481 482 ---------------------------------------- 483 -- Attribute_Constrained_Static_Value -- 484 ---------------------------------------- 485 486 function Attribute_Constrained_Static_Value (Pref : Node_Id) return Boolean 487 is 488 Ptyp : constant Entity_Id := Etype (Pref); 489 Formal_Ent : constant Entity_Id := Param_Entity (Pref); 490 491 function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean; 492 -- Ada 2005 (AI-363): Returns True if the object name Obj denotes a 493 -- view of an aliased object whose subtype is constrained. 494 495 --------------------------------- 496 -- Is_Constrained_Aliased_View -- 497 --------------------------------- 498 499 function Is_Constrained_Aliased_View (Obj : Node_Id) return Boolean is 500 E : Entity_Id; 501 502 begin 503 if Is_Entity_Name (Obj) then 504 E := Entity (Obj); 505 506 if Present (Renamed_Object (E)) then 507 return Is_Constrained_Aliased_View (Renamed_Object (E)); 508 else 509 return Is_Aliased (E) and then Is_Constrained (Etype (E)); 510 end if; 511 512 else 513 return Is_Aliased_View (Obj) 514 and then 515 (Is_Constrained (Etype (Obj)) 516 or else 517 (Nkind (Obj) = N_Explicit_Dereference 518 and then 519 not Object_Type_Has_Constrained_Partial_View 520 (Typ => Base_Type (Etype (Obj)), 521 Scop => Current_Scope))); 522 end if; 523 end Is_Constrained_Aliased_View; 524 525 -- Start of processing for Attribute_Constrained_Static_Value 526 527 begin 528 -- We are in a case where the attribute is known statically, and 529 -- implicit dereferences have been rewritten. 530 531 pragma Assert 532 (not (Present (Formal_Ent) 533 and then Ekind (Formal_Ent) /= E_Constant 534 and then Present (Extra_Constrained (Formal_Ent))) 535 and then 536 not (Is_Access_Type (Etype (Pref)) 537 and then (not Is_Entity_Name (Pref) 538 or else Is_Object (Entity (Pref)))) 539 and then 540 not (Nkind (Pref) = N_Identifier 541 and then Ekind (Entity (Pref)) = E_Variable 542 and then Present (Extra_Constrained (Entity (Pref))))); 543 544 if Is_Entity_Name (Pref) then 545 declare 546 Ent : constant Entity_Id := Entity (Pref); 547 Res : Boolean; 548 549 begin 550 -- (RM J.4) obsolescent cases 551 552 if Is_Type (Ent) then 553 554 -- Private type 555 556 if Is_Private_Type (Ent) then 557 Res := not Has_Discriminants (Ent) 558 or else Is_Constrained (Ent); 559 560 -- It not a private type, must be a generic actual type 561 -- that corresponded to a private type. We know that this 562 -- correspondence holds, since otherwise the reference 563 -- within the generic template would have been illegal. 564 565 else 566 if Is_Composite_Type (Underlying_Type (Ent)) then 567 Res := Is_Constrained (Ent); 568 else 569 Res := True; 570 end if; 571 end if; 572 573 else 574 575 -- If the prefix is not a variable or is aliased, then 576 -- definitely true; if it's a formal parameter without an 577 -- associated extra formal, then treat it as constrained. 578 579 -- Ada 2005 (AI-363): An aliased prefix must be known to be 580 -- constrained in order to set the attribute to True. 581 582 if not Is_Variable (Pref) 583 or else Present (Formal_Ent) 584 or else (Ada_Version < Ada_2005 585 and then Is_Aliased_View (Pref)) 586 or else (Ada_Version >= Ada_2005 587 and then Is_Constrained_Aliased_View (Pref)) 588 then 589 Res := True; 590 591 -- Variable case, look at type to see if it is constrained. 592 -- Note that the one case where this is not accurate (the 593 -- procedure formal case), has been handled above. 594 595 -- We use the Underlying_Type here (and below) in case the 596 -- type is private without discriminants, but the full type 597 -- has discriminants. This case is illegal, but we generate 598 -- it internally for passing to the Extra_Constrained 599 -- parameter. 600 601 else 602 -- In Ada 2012, test for case of a limited tagged type, 603 -- in which case the attribute is always required to 604 -- return True. The underlying type is tested, to make 605 -- sure we also return True for cases where there is an 606 -- unconstrained object with an untagged limited partial 607 -- view which has defaulted discriminants (such objects 608 -- always produce a False in earlier versions of 609 -- Ada). (Ada 2012: AI05-0214) 610 611 Res := 612 Is_Constrained (Underlying_Type (Etype (Ent))) 613 or else 614 (Ada_Version >= Ada_2012 615 and then Is_Tagged_Type (Underlying_Type (Ptyp)) 616 and then Is_Limited_Type (Ptyp)); 617 end if; 618 end if; 619 620 return Res; 621 end; 622 623 -- Prefix is not an entity name. These are also cases where we can 624 -- always tell at compile time by looking at the form and type of the 625 -- prefix. If an explicit dereference of an object with constrained 626 -- partial view, this is unconstrained (Ada 2005: AI95-0363). If the 627 -- underlying type is a limited tagged type, then Constrained is 628 -- required to always return True (Ada 2012: AI05-0214). 629 630 else 631 return not Is_Variable (Pref) 632 or else 633 (Nkind (Pref) = N_Explicit_Dereference 634 and then 635 not Object_Type_Has_Constrained_Partial_View 636 (Typ => Base_Type (Ptyp), 637 Scop => Current_Scope)) 638 or else Is_Constrained (Underlying_Type (Ptyp)) 639 or else (Ada_Version >= Ada_2012 640 and then Is_Tagged_Type (Underlying_Type (Ptyp)) 641 and then Is_Limited_Type (Ptyp)); 642 end if; 643 end Attribute_Constrained_Static_Value; 644 645 ------------------------------------ 646 -- Build_Allocate_Deallocate_Proc -- 647 ------------------------------------ 648 649 procedure Build_Allocate_Deallocate_Proc 650 (N : Node_Id; 651 Is_Allocate : Boolean) 652 is 653 function Find_Object (E : Node_Id) return Node_Id; 654 -- Given an arbitrary expression of an allocator, try to find an object 655 -- reference in it, otherwise return the original expression. 656 657 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean; 658 -- Determine whether subprogram Subp denotes a custom allocate or 659 -- deallocate. 660 661 ----------------- 662 -- Find_Object -- 663 ----------------- 664 665 function Find_Object (E : Node_Id) return Node_Id is 666 Expr : Node_Id; 667 668 begin 669 pragma Assert (Is_Allocate); 670 671 Expr := E; 672 loop 673 if Nkind (Expr) = N_Explicit_Dereference then 674 Expr := Prefix (Expr); 675 676 elsif Nkind (Expr) = N_Qualified_Expression then 677 Expr := Expression (Expr); 678 679 elsif Nkind (Expr) = N_Unchecked_Type_Conversion then 680 681 -- When interface class-wide types are involved in allocation, 682 -- the expander introduces several levels of address arithmetic 683 -- to perform dispatch table displacement. In this scenario the 684 -- object appears as: 685 686 -- Tag_Ptr (Base_Address (<object>'Address)) 687 688 -- Detect this case and utilize the whole expression as the 689 -- "object" since it now points to the proper dispatch table. 690 691 if Is_RTE (Etype (Expr), RE_Tag_Ptr) then 692 exit; 693 694 -- Continue to strip the object 695 696 else 697 Expr := Expression (Expr); 698 end if; 699 700 else 701 exit; 702 end if; 703 end loop; 704 705 return Expr; 706 end Find_Object; 707 708 --------------------------------- 709 -- Is_Allocate_Deallocate_Proc -- 710 --------------------------------- 711 712 function Is_Allocate_Deallocate_Proc (Subp : Entity_Id) return Boolean is 713 begin 714 -- Look for a subprogram body with only one statement which is a 715 -- call to Allocate_Any_Controlled / Deallocate_Any_Controlled. 716 717 if Ekind (Subp) = E_Procedure 718 and then Nkind (Parent (Parent (Subp))) = N_Subprogram_Body 719 then 720 declare 721 HSS : constant Node_Id := 722 Handled_Statement_Sequence (Parent (Parent (Subp))); 723 Proc : Entity_Id; 724 725 begin 726 if Present (Statements (HSS)) 727 and then Nkind (First (Statements (HSS))) = 728 N_Procedure_Call_Statement 729 then 730 Proc := Entity (Name (First (Statements (HSS)))); 731 732 return 733 Is_RTE (Proc, RE_Allocate_Any_Controlled) 734 or else Is_RTE (Proc, RE_Deallocate_Any_Controlled); 735 end if; 736 end; 737 end if; 738 739 return False; 740 end Is_Allocate_Deallocate_Proc; 741 742 -- Local variables 743 744 Desig_Typ : Entity_Id; 745 Expr : Node_Id; 746 Needs_Fin : Boolean; 747 Pool_Id : Entity_Id; 748 Proc_To_Call : Node_Id := Empty; 749 Ptr_Typ : Entity_Id; 750 Use_Secondary_Stack_Pool : Boolean; 751 752 -- Start of processing for Build_Allocate_Deallocate_Proc 753 754 begin 755 -- Obtain the attributes of the allocation / deallocation 756 757 if Nkind (N) = N_Free_Statement then 758 Expr := Expression (N); 759 Ptr_Typ := Base_Type (Etype (Expr)); 760 Proc_To_Call := Procedure_To_Call (N); 761 762 else 763 if Nkind (N) = N_Object_Declaration then 764 Expr := Expression (N); 765 else 766 Expr := N; 767 end if; 768 769 -- In certain cases an allocator with a qualified expression may 770 -- be relocated and used as the initialization expression of a 771 -- temporary: 772 773 -- before: 774 -- Obj : Ptr_Typ := new Desig_Typ'(...); 775 776 -- after: 777 -- Tmp : Ptr_Typ := new Desig_Typ'(...); 778 -- Obj : Ptr_Typ := Tmp; 779 780 -- Since the allocator is always marked as analyzed to avoid infinite 781 -- expansion, it will never be processed by this routine given that 782 -- the designated type needs finalization actions. Detect this case 783 -- and complete the expansion of the allocator. 784 785 if Nkind (Expr) = N_Identifier 786 and then Nkind (Parent (Entity (Expr))) = N_Object_Declaration 787 and then Nkind (Expression (Parent (Entity (Expr)))) = N_Allocator 788 then 789 Build_Allocate_Deallocate_Proc (Parent (Entity (Expr)), True); 790 return; 791 end if; 792 793 -- The allocator may have been rewritten into something else in which 794 -- case the expansion performed by this routine does not apply. 795 796 if Nkind (Expr) /= N_Allocator then 797 return; 798 end if; 799 800 Ptr_Typ := Base_Type (Etype (Expr)); 801 Proc_To_Call := Procedure_To_Call (Expr); 802 end if; 803 804 Pool_Id := Associated_Storage_Pool (Ptr_Typ); 805 Desig_Typ := Available_View (Designated_Type (Ptr_Typ)); 806 807 -- Handle concurrent types 808 809 if Is_Concurrent_Type (Desig_Typ) 810 and then Present (Corresponding_Record_Type (Desig_Typ)) 811 then 812 Desig_Typ := Corresponding_Record_Type (Desig_Typ); 813 end if; 814 815 Use_Secondary_Stack_Pool := 816 Is_RTE (Pool_Id, RE_SS_Pool) 817 or else (Nkind (Expr) = N_Allocator 818 and then Is_RTE (Storage_Pool (Expr), RE_SS_Pool)); 819 820 -- Do not process allocations / deallocations without a pool 821 822 if No (Pool_Id) then 823 return; 824 825 -- Do not process allocations on / deallocations from the secondary 826 -- stack, except for access types used to implement indirect temps. 827 828 elsif Use_Secondary_Stack_Pool 829 and then not Old_Attr_Util.Indirect_Temps 830 .Is_Access_Type_For_Indirect_Temp (Ptr_Typ) 831 then 832 return; 833 834 -- Optimize the case where we are using the default Global_Pool_Object, 835 -- and we don't need the heavy finalization machinery. 836 837 elsif Pool_Id = RTE (RE_Global_Pool_Object) 838 and then not Needs_Finalization (Desig_Typ) 839 then 840 return; 841 842 -- Do not replicate the machinery if the allocator / free has already 843 -- been expanded and has a custom Allocate / Deallocate. 844 845 elsif Present (Proc_To_Call) 846 and then Is_Allocate_Deallocate_Proc (Proc_To_Call) 847 then 848 return; 849 end if; 850 851 -- Finalization actions are required when the object to be allocated or 852 -- deallocated needs these actions and the associated access type is not 853 -- subject to pragma No_Heap_Finalization. 854 855 Needs_Fin := 856 Needs_Finalization (Desig_Typ) 857 and then not No_Heap_Finalization (Ptr_Typ); 858 859 if Needs_Fin then 860 861 -- Do nothing if the access type may never allocate / deallocate 862 -- objects. 863 864 if No_Pool_Assigned (Ptr_Typ) then 865 return; 866 end if; 867 868 -- The allocation / deallocation of a controlled object must be 869 -- chained on / detached from a finalization master. 870 871 pragma Assert (Present (Finalization_Master (Ptr_Typ))); 872 873 -- The only other kind of allocation / deallocation supported by this 874 -- routine is on / from a subpool. 875 876 elsif Nkind (Expr) = N_Allocator 877 and then No (Subpool_Handle_Name (Expr)) 878 then 879 return; 880 end if; 881 882 declare 883 Loc : constant Source_Ptr := Sloc (N); 884 Addr_Id : constant Entity_Id := Make_Temporary (Loc, 'A'); 885 Alig_Id : constant Entity_Id := Make_Temporary (Loc, 'L'); 886 Proc_Id : constant Entity_Id := Make_Temporary (Loc, 'P'); 887 Size_Id : constant Entity_Id := Make_Temporary (Loc, 'S'); 888 889 Actuals : List_Id; 890 Fin_Addr_Id : Entity_Id; 891 Fin_Mas_Act : Node_Id; 892 Fin_Mas_Id : Entity_Id; 893 Proc_To_Call : Entity_Id; 894 Subpool : Node_Id := Empty; 895 896 begin 897 -- Step 1: Construct all the actuals for the call to library routine 898 -- Allocate_Any_Controlled / Deallocate_Any_Controlled. 899 900 -- a) Storage pool 901 902 Actuals := New_List (New_Occurrence_Of (Pool_Id, Loc)); 903 904 if Is_Allocate then 905 906 -- b) Subpool 907 908 if Nkind (Expr) = N_Allocator then 909 Subpool := Subpool_Handle_Name (Expr); 910 end if; 911 912 -- If a subpool is present it can be an arbitrary name, so make 913 -- the actual by copying the tree. 914 915 if Present (Subpool) then 916 Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc)); 917 else 918 Append_To (Actuals, Make_Null (Loc)); 919 end if; 920 921 -- c) Finalization master 922 923 if Needs_Fin then 924 Fin_Mas_Id := Finalization_Master (Ptr_Typ); 925 Fin_Mas_Act := New_Occurrence_Of (Fin_Mas_Id, Loc); 926 927 -- Handle the case where the master is actually a pointer to a 928 -- master. This case arises in build-in-place functions. 929 930 if Is_Access_Type (Etype (Fin_Mas_Id)) then 931 Append_To (Actuals, Fin_Mas_Act); 932 else 933 Append_To (Actuals, 934 Make_Attribute_Reference (Loc, 935 Prefix => Fin_Mas_Act, 936 Attribute_Name => Name_Unrestricted_Access)); 937 end if; 938 else 939 Append_To (Actuals, Make_Null (Loc)); 940 end if; 941 942 -- d) Finalize_Address 943 944 -- Primitive Finalize_Address is never generated in CodePeer mode 945 -- since it contains an Unchecked_Conversion. 946 947 if Needs_Fin and then not CodePeer_Mode then 948 Fin_Addr_Id := Finalize_Address (Desig_Typ); 949 pragma Assert (Present (Fin_Addr_Id)); 950 951 Append_To (Actuals, 952 Make_Attribute_Reference (Loc, 953 Prefix => New_Occurrence_Of (Fin_Addr_Id, Loc), 954 Attribute_Name => Name_Unrestricted_Access)); 955 else 956 Append_To (Actuals, Make_Null (Loc)); 957 end if; 958 end if; 959 960 -- e) Address 961 -- f) Storage_Size 962 -- g) Alignment 963 964 Append_To (Actuals, New_Occurrence_Of (Addr_Id, Loc)); 965 Append_To (Actuals, New_Occurrence_Of (Size_Id, Loc)); 966 967 if (Is_Allocate or else not Is_Class_Wide_Type (Desig_Typ)) 968 and then not Use_Secondary_Stack_Pool 969 then 970 Append_To (Actuals, New_Occurrence_Of (Alig_Id, Loc)); 971 972 -- For deallocation of class-wide types we obtain the value of 973 -- alignment from the Type Specific Record of the deallocated object. 974 -- This is needed because the frontend expansion of class-wide types 975 -- into equivalent types confuses the back end. 976 977 else 978 -- Generate: 979 -- Obj.all'Alignment 980 981 -- ... because 'Alignment applied to class-wide types is expanded 982 -- into the code that reads the value of alignment from the TSD 983 -- (see Expand_N_Attribute_Reference) 984 985 -- In the Use_Secondary_Stack_Pool case, Alig_Id is not 986 -- passed in and therefore must not be referenced. 987 988 Append_To (Actuals, 989 Unchecked_Convert_To (RTE (RE_Storage_Offset), 990 Make_Attribute_Reference (Loc, 991 Prefix => 992 Make_Explicit_Dereference (Loc, Relocate_Node (Expr)), 993 Attribute_Name => Name_Alignment))); 994 end if; 995 996 -- h) Is_Controlled 997 998 if Needs_Fin then 999 Is_Controlled : declare 1000 Flag_Id : constant Entity_Id := Make_Temporary (Loc, 'F'); 1001 Flag_Expr : Node_Id; 1002 Param : Node_Id; 1003 Pref : Node_Id; 1004 Temp : Node_Id; 1005 1006 begin 1007 if Is_Allocate then 1008 Temp := Find_Object (Expression (Expr)); 1009 else 1010 Temp := Expr; 1011 end if; 1012 1013 -- Processing for allocations where the expression is a subtype 1014 -- indication. 1015 1016 if Is_Allocate 1017 and then Is_Entity_Name (Temp) 1018 and then Is_Type (Entity (Temp)) 1019 then 1020 Flag_Expr := 1021 New_Occurrence_Of 1022 (Boolean_Literals 1023 (Needs_Finalization (Entity (Temp))), Loc); 1024 1025 -- The allocation / deallocation of a class-wide object relies 1026 -- on a runtime check to determine whether the object is truly 1027 -- controlled or not. Depending on this check, the finalization 1028 -- machinery will request or reclaim extra storage reserved for 1029 -- a list header. 1030 1031 elsif Is_Class_Wide_Type (Desig_Typ) then 1032 1033 -- Detect a special case where interface class-wide types 1034 -- are involved as the object appears as: 1035 1036 -- Tag_Ptr (Base_Address (<object>'Address)) 1037 1038 -- The expression already yields the proper tag, generate: 1039 1040 -- Temp.all 1041 1042 if Is_RTE (Etype (Temp), RE_Tag_Ptr) then 1043 Param := 1044 Make_Explicit_Dereference (Loc, 1045 Prefix => Relocate_Node (Temp)); 1046 1047 -- In the default case, obtain the tag of the object about 1048 -- to be allocated / deallocated. Generate: 1049 1050 -- Temp'Tag 1051 1052 -- If the object is an unchecked conversion (typically to 1053 -- an access to class-wide type), we must preserve the 1054 -- conversion to ensure that the object is seen as tagged 1055 -- in the code that follows. 1056 1057 else 1058 Pref := Temp; 1059 1060 if Nkind (Parent (Pref)) = N_Unchecked_Type_Conversion 1061 then 1062 Pref := Parent (Pref); 1063 end if; 1064 1065 Param := 1066 Make_Attribute_Reference (Loc, 1067 Prefix => Relocate_Node (Pref), 1068 Attribute_Name => Name_Tag); 1069 end if; 1070 1071 -- Generate: 1072 -- Needs_Finalization (<Param>) 1073 1074 Flag_Expr := 1075 Make_Function_Call (Loc, 1076 Name => 1077 New_Occurrence_Of (RTE (RE_Needs_Finalization), Loc), 1078 Parameter_Associations => New_List (Param)); 1079 1080 -- Processing for generic actuals 1081 1082 elsif Is_Generic_Actual_Type (Desig_Typ) then 1083 Flag_Expr := 1084 New_Occurrence_Of (Boolean_Literals 1085 (Needs_Finalization (Base_Type (Desig_Typ))), Loc); 1086 1087 -- The object does not require any specialized checks, it is 1088 -- known to be controlled. 1089 1090 else 1091 Flag_Expr := New_Occurrence_Of (Standard_True, Loc); 1092 end if; 1093 1094 -- Create the temporary which represents the finalization state 1095 -- of the expression. Generate: 1096 -- 1097 -- F : constant Boolean := <Flag_Expr>; 1098 1099 Insert_Action (N, 1100 Make_Object_Declaration (Loc, 1101 Defining_Identifier => Flag_Id, 1102 Constant_Present => True, 1103 Object_Definition => 1104 New_Occurrence_Of (Standard_Boolean, Loc), 1105 Expression => Flag_Expr)); 1106 1107 Append_To (Actuals, New_Occurrence_Of (Flag_Id, Loc)); 1108 end Is_Controlled; 1109 1110 -- The object is not controlled 1111 1112 else 1113 Append_To (Actuals, New_Occurrence_Of (Standard_False, Loc)); 1114 end if; 1115 1116 -- i) On_Subpool 1117 1118 if Is_Allocate then 1119 Append_To (Actuals, 1120 New_Occurrence_Of (Boolean_Literals (Present (Subpool)), Loc)); 1121 end if; 1122 1123 -- Step 2: Build a wrapper Allocate / Deallocate which internally 1124 -- calls Allocate_Any_Controlled / Deallocate_Any_Controlled. 1125 1126 -- Select the proper routine to call 1127 1128 if Is_Allocate then 1129 Proc_To_Call := RTE (RE_Allocate_Any_Controlled); 1130 else 1131 Proc_To_Call := RTE (RE_Deallocate_Any_Controlled); 1132 end if; 1133 1134 -- Create a custom Allocate / Deallocate routine which has identical 1135 -- profile to that of System.Storage_Pools. 1136 1137 declare 1138 -- P : Root_Storage_Pool 1139 function Pool_Param return Node_Id is ( 1140 Make_Parameter_Specification (Loc, 1141 Defining_Identifier => Make_Temporary (Loc, 'P'), 1142 Parameter_Type => 1143 New_Occurrence_Of (RTE (RE_Root_Storage_Pool), Loc))); 1144 1145 -- A : [out] Address 1146 function Address_Param return Node_Id is ( 1147 Make_Parameter_Specification (Loc, 1148 Defining_Identifier => Addr_Id, 1149 Out_Present => Is_Allocate, 1150 Parameter_Type => 1151 New_Occurrence_Of (RTE (RE_Address), Loc))); 1152 1153 -- S : Storage_Count 1154 function Size_Param return Node_Id is ( 1155 Make_Parameter_Specification (Loc, 1156 Defining_Identifier => Size_Id, 1157 Parameter_Type => 1158 New_Occurrence_Of (RTE (RE_Storage_Count), Loc))); 1159 1160 -- L : Storage_Count 1161 function Alignment_Param return Node_Id is ( 1162 Make_Parameter_Specification (Loc, 1163 Defining_Identifier => Alig_Id, 1164 Parameter_Type => 1165 New_Occurrence_Of (RTE (RE_Storage_Count), Loc))); 1166 1167 Formal_Params : List_Id; 1168 begin 1169 if Use_Secondary_Stack_Pool then 1170 -- Gigi expects a different profile in the Secondary_Stack_Pool 1171 -- case. There must be no uses of the two missing formals 1172 -- (i.e., Pool_Param and Alignment_Param) in this case. 1173 Formal_Params := New_List (Address_Param, Size_Param); 1174 else 1175 Formal_Params := New_List ( 1176 Pool_Param, Address_Param, Size_Param, Alignment_Param); 1177 end if; 1178 1179 Insert_Action (N, 1180 Make_Subprogram_Body (Loc, 1181 Specification => 1182 -- procedure Pnn 1183 Make_Procedure_Specification (Loc, 1184 Defining_Unit_Name => Proc_Id, 1185 Parameter_Specifications => Formal_Params), 1186 1187 Declarations => No_List, 1188 1189 Handled_Statement_Sequence => 1190 Make_Handled_Sequence_Of_Statements (Loc, 1191 Statements => New_List ( 1192 Make_Procedure_Call_Statement (Loc, 1193 Name => 1194 New_Occurrence_Of (Proc_To_Call, Loc), 1195 Parameter_Associations => Actuals)))), 1196 Suppress => All_Checks); 1197 end; 1198 1199 -- The newly generated Allocate / Deallocate becomes the default 1200 -- procedure to call when the back end processes the allocation / 1201 -- deallocation. 1202 1203 if Is_Allocate then 1204 Set_Procedure_To_Call (Expr, Proc_Id); 1205 else 1206 Set_Procedure_To_Call (N, Proc_Id); 1207 end if; 1208 end; 1209 end Build_Allocate_Deallocate_Proc; 1210 1211 ------------------------------- 1212 -- Build_Abort_Undefer_Block -- 1213 ------------------------------- 1214 1215 function Build_Abort_Undefer_Block 1216 (Loc : Source_Ptr; 1217 Stmts : List_Id; 1218 Context : Node_Id) return Node_Id 1219 is 1220 Exceptions_OK : constant Boolean := 1221 not Restriction_Active (No_Exception_Propagation); 1222 1223 AUD : Entity_Id; 1224 Blk : Node_Id; 1225 Blk_Id : Entity_Id; 1226 HSS : Node_Id; 1227 1228 begin 1229 -- The block should be generated only when undeferring abort in the 1230 -- context of a potential exception. 1231 1232 pragma Assert (Abort_Allowed and Exceptions_OK); 1233 1234 -- Generate: 1235 -- begin 1236 -- <Stmts> 1237 -- at end 1238 -- Abort_Undefer_Direct; 1239 -- end; 1240 1241 AUD := RTE (RE_Abort_Undefer_Direct); 1242 1243 HSS := 1244 Make_Handled_Sequence_Of_Statements (Loc, 1245 Statements => Stmts, 1246 At_End_Proc => New_Occurrence_Of (AUD, Loc)); 1247 1248 Blk := 1249 Make_Block_Statement (Loc, 1250 Handled_Statement_Sequence => HSS); 1251 Set_Is_Abort_Block (Blk); 1252 1253 Add_Block_Identifier (Blk, Blk_Id); 1254 Expand_At_End_Handler (HSS, Blk_Id); 1255 1256 -- Present the Abort_Undefer_Direct function to the back end to inline 1257 -- the call to the routine. 1258 1259 Add_Inlined_Body (AUD, Context); 1260 1261 return Blk; 1262 end Build_Abort_Undefer_Block; 1263 1264 --------------------------------- 1265 -- Build_Class_Wide_Expression -- 1266 --------------------------------- 1267 1268 procedure Build_Class_Wide_Expression 1269 (Prag : Node_Id; 1270 Subp : Entity_Id; 1271 Par_Subp : Entity_Id; 1272 Adjust_Sloc : Boolean; 1273 Needs_Wrapper : out Boolean) 1274 is 1275 function Replace_Entity (N : Node_Id) return Traverse_Result; 1276 -- Replace reference to formal of inherited operation or to primitive 1277 -- operation of root type, with corresponding entity for derived type, 1278 -- when constructing the class-wide condition of an overriding 1279 -- subprogram. 1280 1281 -------------------- 1282 -- Replace_Entity -- 1283 -------------------- 1284 1285 function Replace_Entity (N : Node_Id) return Traverse_Result is 1286 New_E : Entity_Id; 1287 1288 begin 1289 if Adjust_Sloc then 1290 Adjust_Inherited_Pragma_Sloc (N); 1291 end if; 1292 1293 if Nkind (N) = N_Identifier 1294 and then Present (Entity (N)) 1295 and then 1296 (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N))) 1297 and then 1298 (Nkind (Parent (N)) /= N_Attribute_Reference 1299 or else Attribute_Name (Parent (N)) /= Name_Class) 1300 then 1301 -- The replacement does not apply to dispatching calls within the 1302 -- condition, but only to calls whose static tag is that of the 1303 -- parent type. 1304 1305 if Is_Subprogram (Entity (N)) 1306 and then Nkind (Parent (N)) = N_Function_Call 1307 and then Present (Controlling_Argument (Parent (N))) 1308 then 1309 return OK; 1310 end if; 1311 1312 -- Determine whether entity has a renaming 1313 1314 New_E := Type_Map.Get (Entity (N)); 1315 1316 if Present (New_E) then 1317 Rewrite (N, New_Occurrence_Of (New_E, Sloc (N))); 1318 1319 -- AI12-0166: a precondition for a protected operation 1320 -- cannot include an internal call to a protected function 1321 -- of the type. In the case of an inherited condition for an 1322 -- overriding operation, both the operation and the function 1323 -- are given by primitive wrappers. 1324 -- Move this check to sem??? 1325 1326 if Ekind (New_E) = E_Function 1327 and then Is_Primitive_Wrapper (New_E) 1328 and then Is_Primitive_Wrapper (Subp) 1329 and then Scope (Subp) = Scope (New_E) 1330 then 1331 Error_Msg_Node_2 := Wrapped_Entity (Subp); 1332 Error_Msg_NE 1333 ("internal call to& cannot appear in inherited " 1334 & "precondition of protected operation&", 1335 N, Wrapped_Entity (New_E)); 1336 end if; 1337 1338 -- If the entity is an overridden primitive and we are not 1339 -- in GNATprove mode, we must build a wrapper for the current 1340 -- inherited operation. If the reference is the prefix of an 1341 -- attribute such as 'Result (or others ???) there is no need 1342 -- for a wrapper: the condition is just rewritten in terms of 1343 -- the inherited subprogram. 1344 1345 if Is_Subprogram (New_E) 1346 and then Nkind (Parent (N)) /= N_Attribute_Reference 1347 and then not GNATprove_Mode 1348 then 1349 Needs_Wrapper := True; 1350 end if; 1351 end if; 1352 1353 -- Check that there are no calls left to abstract operations if 1354 -- the current subprogram is not abstract. 1355 -- Move this check to sem??? 1356 1357 if Nkind (Parent (N)) = N_Function_Call 1358 and then N = Name (Parent (N)) 1359 then 1360 if not Is_Abstract_Subprogram (Subp) 1361 and then Is_Abstract_Subprogram (Entity (N)) 1362 then 1363 Error_Msg_Sloc := Sloc (Current_Scope); 1364 Error_Msg_Node_2 := Subp; 1365 if Comes_From_Source (Subp) then 1366 Error_Msg_NE 1367 ("cannot call abstract subprogram & in inherited " 1368 & "condition for&#", Subp, Entity (N)); 1369 else 1370 Error_Msg_NE 1371 ("cannot call abstract subprogram & in inherited " 1372 & "condition for inherited&#", Subp, Entity (N)); 1373 end if; 1374 1375 -- In SPARK mode, reject an inherited condition for an 1376 -- inherited operation if it contains a call to an overriding 1377 -- operation, because this implies that the pre/postconditions 1378 -- of the inherited operation have changed silently. 1379 1380 elsif SPARK_Mode = On 1381 and then Warn_On_Suspicious_Contract 1382 and then Present (Alias (Subp)) 1383 and then Present (New_E) 1384 and then Comes_From_Source (New_E) 1385 then 1386 Error_Msg_N 1387 ("cannot modify inherited condition (SPARK RM 6.1.1(1))", 1388 Parent (Subp)); 1389 Error_Msg_Sloc := Sloc (New_E); 1390 Error_Msg_Node_2 := Subp; 1391 Error_Msg_NE 1392 ("\overriding of&# forces overriding of&", 1393 Parent (Subp), New_E); 1394 end if; 1395 end if; 1396 1397 -- Update type of function call node, which should be the same as 1398 -- the function's return type. 1399 1400 if Is_Subprogram (Entity (N)) 1401 and then Nkind (Parent (N)) = N_Function_Call 1402 then 1403 Set_Etype (Parent (N), Etype (Entity (N))); 1404 end if; 1405 1406 -- The whole expression will be reanalyzed 1407 1408 elsif Nkind (N) in N_Has_Etype then 1409 Set_Analyzed (N, False); 1410 end if; 1411 1412 return OK; 1413 end Replace_Entity; 1414 1415 procedure Replace_Condition_Entities is 1416 new Traverse_Proc (Replace_Entity); 1417 1418 -- Local variables 1419 1420 Par_Formal : Entity_Id; 1421 Subp_Formal : Entity_Id; 1422 1423 -- Start of processing for Build_Class_Wide_Expression 1424 1425 begin 1426 Needs_Wrapper := False; 1427 1428 -- Add mapping from old formals to new formals 1429 1430 Par_Formal := First_Formal (Par_Subp); 1431 Subp_Formal := First_Formal (Subp); 1432 1433 while Present (Par_Formal) and then Present (Subp_Formal) loop 1434 Type_Map.Set (Par_Formal, Subp_Formal); 1435 Next_Formal (Par_Formal); 1436 Next_Formal (Subp_Formal); 1437 end loop; 1438 1439 Replace_Condition_Entities (Prag); 1440 end Build_Class_Wide_Expression; 1441 1442 -------------------- 1443 -- Build_DIC_Call -- 1444 -------------------- 1445 1446 function Build_DIC_Call 1447 (Loc : Source_Ptr; 1448 Obj_Name : Node_Id; 1449 Typ : Entity_Id) return Node_Id 1450 is 1451 Proc_Id : constant Entity_Id := DIC_Procedure (Typ); 1452 Formal_Typ : constant Entity_Id := Etype (First_Formal (Proc_Id)); 1453 1454 begin 1455 -- The DIC procedure has a null body if assertions are disabled or 1456 -- Assertion_Policy Ignore is in effect. In that case, it would be 1457 -- nice to generate a null statement instead of a call to the DIC 1458 -- procedure, but doing that seems to interfere with the determination 1459 -- of ECRs (early call regions) in SPARK. ??? 1460 1461 return 1462 Make_Procedure_Call_Statement (Loc, 1463 Name => New_Occurrence_Of (Proc_Id, Loc), 1464 Parameter_Associations => New_List ( 1465 Make_Unchecked_Type_Conversion (Loc, 1466 Subtype_Mark => New_Occurrence_Of (Formal_Typ, Loc), 1467 Expression => Obj_Name))); 1468 end Build_DIC_Call; 1469 1470 ------------------------------ 1471 -- Build_DIC_Procedure_Body -- 1472 ------------------------------ 1473 1474 -- WARNING: This routine manages Ghost regions. Return statements must be 1475 -- replaced by gotos which jump to the end of the routine and restore the 1476 -- Ghost mode. 1477 1478 procedure Build_DIC_Procedure_Body 1479 (Typ : Entity_Id; 1480 Partial_DIC : Boolean := False) 1481 is 1482 Pragmas_Seen : Elist_Id := No_Elist; 1483 -- This list contains all DIC pragmas processed so far. The list is used 1484 -- to avoid redundant Default_Initial_Condition checks. 1485 1486 procedure Add_DIC_Check 1487 (DIC_Prag : Node_Id; 1488 DIC_Expr : Node_Id; 1489 Stmts : in out List_Id); 1490 -- Subsidiary to all Add_xxx_DIC routines. Add a runtime check to verify 1491 -- assertion expression DIC_Expr of pragma DIC_Prag. All generated code 1492 -- is added to list Stmts. 1493 1494 procedure Add_Inherited_DIC 1495 (DIC_Prag : Node_Id; 1496 Par_Typ : Entity_Id; 1497 Deriv_Typ : Entity_Id; 1498 Stmts : in out List_Id); 1499 -- Add a runtime check to verify the assertion expression of inherited 1500 -- pragma DIC_Prag. Par_Typ is parent type, which is also the owner of 1501 -- the DIC pragma. Deriv_Typ is the derived type inheriting the DIC 1502 -- pragma. All generated code is added to list Stmts. 1503 1504 procedure Add_Inherited_Tagged_DIC 1505 (DIC_Prag : Node_Id; 1506 Expr : Node_Id; 1507 Stmts : in out List_Id); 1508 -- Add a runtime check to verify assertion expression DIC_Expr of 1509 -- inherited pragma DIC_Prag. This routine applies class-wide pre- 1510 -- and postcondition-like runtime semantics to the check. Expr is 1511 -- the assertion expression after substitition has been performed 1512 -- (via Replace_References). All generated code is added to list Stmts. 1513 1514 procedure Add_Inherited_DICs 1515 (T : Entity_Id; 1516 Priv_Typ : Entity_Id; 1517 Full_Typ : Entity_Id; 1518 Obj_Id : Entity_Id; 1519 Checks : in out List_Id); 1520 -- Generate a DIC check for each inherited Default_Initial_Condition 1521 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote 1522 -- the partial and full view of the parent type. Obj_Id denotes the 1523 -- entity of the _object formal parameter of the DIC procedure. All 1524 -- created checks are added to list Checks. 1525 1526 procedure Add_Own_DIC 1527 (DIC_Prag : Node_Id; 1528 DIC_Typ : Entity_Id; 1529 Obj_Id : Entity_Id; 1530 Stmts : in out List_Id); 1531 -- Add a runtime check to verify the assertion expression of pragma 1532 -- DIC_Prag. DIC_Typ is the owner of the DIC pragma. Obj_Id is the 1533 -- object to substitute in the assertion expression for any references 1534 -- to the current instance of the type All generated code is added to 1535 -- list Stmts. 1536 1537 procedure Add_Parent_DICs 1538 (T : Entity_Id; 1539 Obj_Id : Entity_Id; 1540 Checks : in out List_Id); 1541 -- Generate a Default_Initial_Condition check for each inherited DIC 1542 -- aspect coming from all parent types of type T. Obj_Id denotes the 1543 -- entity of the _object formal parameter of the DIC procedure. All 1544 -- created checks are added to list Checks. 1545 1546 ------------------- 1547 -- Add_DIC_Check -- 1548 ------------------- 1549 1550 procedure Add_DIC_Check 1551 (DIC_Prag : Node_Id; 1552 DIC_Expr : Node_Id; 1553 Stmts : in out List_Id) 1554 is 1555 Loc : constant Source_Ptr := Sloc (DIC_Prag); 1556 Nam : constant Name_Id := Original_Aspect_Pragma_Name (DIC_Prag); 1557 1558 begin 1559 -- The DIC pragma is ignored, nothing left to do 1560 1561 if Is_Ignored (DIC_Prag) then 1562 null; 1563 1564 -- Otherwise the DIC expression must be checked at run time. 1565 -- Generate: 1566 1567 -- pragma Check (<Nam>, <DIC_Expr>); 1568 1569 else 1570 Append_New_To (Stmts, 1571 Make_Pragma (Loc, 1572 Pragma_Identifier => 1573 Make_Identifier (Loc, Name_Check), 1574 1575 Pragma_Argument_Associations => New_List ( 1576 Make_Pragma_Argument_Association (Loc, 1577 Expression => Make_Identifier (Loc, Nam)), 1578 1579 Make_Pragma_Argument_Association (Loc, 1580 Expression => DIC_Expr)))); 1581 end if; 1582 1583 -- Add the pragma to the list of processed pragmas 1584 1585 Append_New_Elmt (DIC_Prag, Pragmas_Seen); 1586 end Add_DIC_Check; 1587 1588 ----------------------- 1589 -- Add_Inherited_DIC -- 1590 ----------------------- 1591 1592 procedure Add_Inherited_DIC 1593 (DIC_Prag : Node_Id; 1594 Par_Typ : Entity_Id; 1595 Deriv_Typ : Entity_Id; 1596 Stmts : in out List_Id) 1597 is 1598 Deriv_Proc : constant Entity_Id := DIC_Procedure (Deriv_Typ); 1599 Deriv_Obj : constant Entity_Id := First_Entity (Deriv_Proc); 1600 Par_Proc : constant Entity_Id := DIC_Procedure (Par_Typ); 1601 Par_Obj : constant Entity_Id := First_Entity (Par_Proc); 1602 Loc : constant Source_Ptr := Sloc (DIC_Prag); 1603 1604 begin 1605 pragma Assert (Present (Deriv_Proc) and then Present (Par_Proc)); 1606 1607 -- Verify the inherited DIC assertion expression by calling the DIC 1608 -- procedure of the parent type. 1609 1610 -- Generate: 1611 -- <Par_Typ>DIC (Par_Typ (_object)); 1612 1613 Append_New_To (Stmts, 1614 Make_Procedure_Call_Statement (Loc, 1615 Name => New_Occurrence_Of (Par_Proc, Loc), 1616 Parameter_Associations => New_List ( 1617 Convert_To 1618 (Typ => Etype (Par_Obj), 1619 Expr => New_Occurrence_Of (Deriv_Obj, Loc))))); 1620 end Add_Inherited_DIC; 1621 1622 ------------------------------ 1623 -- Add_Inherited_Tagged_DIC -- 1624 ------------------------------ 1625 1626 procedure Add_Inherited_Tagged_DIC 1627 (DIC_Prag : Node_Id; 1628 Expr : Node_Id; 1629 Stmts : in out List_Id) 1630 is 1631 begin 1632 -- Once the DIC assertion expression is fully processed, add a check 1633 -- to the statements of the DIC procedure. 1634 1635 Add_DIC_Check 1636 (DIC_Prag => DIC_Prag, 1637 DIC_Expr => Expr, 1638 Stmts => Stmts); 1639 end Add_Inherited_Tagged_DIC; 1640 1641 ------------------------ 1642 -- Add_Inherited_DICs -- 1643 ------------------------ 1644 1645 procedure Add_Inherited_DICs 1646 (T : Entity_Id; 1647 Priv_Typ : Entity_Id; 1648 Full_Typ : Entity_Id; 1649 Obj_Id : Entity_Id; 1650 Checks : in out List_Id) 1651 is 1652 Deriv_Typ : Entity_Id; 1653 Expr : Node_Id; 1654 Prag : Node_Id; 1655 Prag_Expr : Node_Id; 1656 Prag_Expr_Arg : Node_Id; 1657 Prag_Typ : Node_Id; 1658 Prag_Typ_Arg : Node_Id; 1659 1660 Par_Proc : Entity_Id; 1661 -- The "partial" invariant procedure of Par_Typ 1662 1663 Par_Typ : Entity_Id; 1664 -- The suitable view of the parent type used in the substitution of 1665 -- type attributes. 1666 1667 begin 1668 if not Present (Priv_Typ) and then not Present (Full_Typ) then 1669 return; 1670 end if; 1671 1672 -- When the type inheriting the class-wide invariant is a concurrent 1673 -- type, use the corresponding record type because it contains all 1674 -- primitive operations of the concurrent type and allows for proper 1675 -- substitution. 1676 1677 if Is_Concurrent_Type (T) then 1678 Deriv_Typ := Corresponding_Record_Type (T); 1679 else 1680 Deriv_Typ := T; 1681 end if; 1682 1683 pragma Assert (Present (Deriv_Typ)); 1684 1685 -- Determine which rep item chain to use. Precedence is given to that 1686 -- of the parent type's partial view since it usually carries all the 1687 -- class-wide invariants. 1688 1689 if Present (Priv_Typ) then 1690 Prag := First_Rep_Item (Priv_Typ); 1691 else 1692 Prag := First_Rep_Item (Full_Typ); 1693 end if; 1694 1695 while Present (Prag) loop 1696 if Nkind (Prag) = N_Pragma 1697 and then Pragma_Name (Prag) = Name_Default_Initial_Condition 1698 then 1699 -- Nothing to do if the pragma was already processed 1700 1701 if Contains (Pragmas_Seen, Prag) then 1702 return; 1703 end if; 1704 1705 -- Extract arguments of the Default_Initial_Condition pragma 1706 1707 Prag_Expr_Arg := First (Pragma_Argument_Associations (Prag)); 1708 Prag_Expr := Expression_Copy (Prag_Expr_Arg); 1709 1710 -- Pick up the implicit second argument of the pragma, which 1711 -- indicates the type that the pragma applies to. 1712 1713 Prag_Typ_Arg := Next (Prag_Expr_Arg); 1714 if Present (Prag_Typ_Arg) then 1715 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg); 1716 else 1717 Prag_Typ := Empty; 1718 end if; 1719 1720 -- The pragma applies to the partial view of the parent type 1721 1722 if Present (Priv_Typ) 1723 and then Present (Prag_Typ) 1724 and then Entity (Prag_Typ) = Priv_Typ 1725 then 1726 Par_Typ := Priv_Typ; 1727 1728 -- The pragma applies to the full view of the parent type 1729 1730 elsif Present (Full_Typ) 1731 and then Present (Prag_Typ) 1732 and then Entity (Prag_Typ) = Full_Typ 1733 then 1734 Par_Typ := Full_Typ; 1735 1736 -- Otherwise the pragma does not belong to the parent type and 1737 -- should not be considered. 1738 1739 else 1740 return; 1741 end if; 1742 1743 -- Substitute references in the DIC expression that are related 1744 -- to the partial type with corresponding references related to 1745 -- the derived type (call to Replace_References below). 1746 1747 Expr := New_Copy_Tree (Prag_Expr); 1748 1749 Par_Proc := Partial_DIC_Procedure (Par_Typ); 1750 1751 -- If there's not a partial DIC procedure (such as when a 1752 -- full type doesn't have its own DIC, but is inherited from 1753 -- a type with DIC), get the full DIC procedure. 1754 1755 if not Present (Par_Proc) then 1756 Par_Proc := DIC_Procedure (Par_Typ); 1757 end if; 1758 1759 Replace_References 1760 (Expr => Expr, 1761 Par_Typ => Par_Typ, 1762 Deriv_Typ => Deriv_Typ, 1763 Par_Obj => First_Formal (Par_Proc), 1764 Deriv_Obj => Obj_Id); 1765 1766 -- Why are there different actions depending on whether T is 1767 -- tagged? Can these be unified? ??? 1768 1769 if Is_Tagged_Type (T) then 1770 Add_Inherited_Tagged_DIC 1771 (DIC_Prag => Prag, 1772 Expr => Expr, 1773 Stmts => Checks); 1774 1775 else 1776 Add_Inherited_DIC 1777 (DIC_Prag => Prag, 1778 Par_Typ => Par_Typ, 1779 Deriv_Typ => Deriv_Typ, 1780 Stmts => Checks); 1781 end if; 1782 1783 -- Leave as soon as we get a DIC pragma, since we'll visit 1784 -- the pragmas of the parents, so will get to any "inherited" 1785 -- pragmas that way. 1786 1787 return; 1788 end if; 1789 1790 Next_Rep_Item (Prag); 1791 end loop; 1792 end Add_Inherited_DICs; 1793 1794 ----------------- 1795 -- Add_Own_DIC -- 1796 ----------------- 1797 1798 procedure Add_Own_DIC 1799 (DIC_Prag : Node_Id; 1800 DIC_Typ : Entity_Id; 1801 Obj_Id : Entity_Id; 1802 Stmts : in out List_Id) 1803 is 1804 DIC_Args : constant List_Id := 1805 Pragma_Argument_Associations (DIC_Prag); 1806 DIC_Arg : constant Node_Id := First (DIC_Args); 1807 DIC_Asp : constant Node_Id := Corresponding_Aspect (DIC_Prag); 1808 DIC_Expr : constant Node_Id := Get_Pragma_Arg (DIC_Arg); 1809 1810 -- Local variables 1811 1812 Typ_Decl : constant Node_Id := Declaration_Node (DIC_Typ); 1813 1814 Expr : Node_Id; 1815 1816 -- Start of processing for Add_Own_DIC 1817 1818 begin 1819 pragma Assert (Present (DIC_Expr)); 1820 Expr := New_Copy_Tree (DIC_Expr); 1821 1822 -- Perform the following substitution: 1823 1824 -- * Replace the current instance of DIC_Typ with a reference to 1825 -- the _object formal parameter of the DIC procedure. 1826 1827 Replace_Type_References 1828 (Expr => Expr, 1829 Typ => DIC_Typ, 1830 Obj_Id => Obj_Id); 1831 1832 -- Preanalyze the DIC expression to detect errors and at the same 1833 -- time capture the visibility of the proper package part. 1834 1835 Set_Parent (Expr, Typ_Decl); 1836 Preanalyze_Assert_Expression (Expr, Any_Boolean); 1837 1838 -- Save a copy of the expression with all replacements and analysis 1839 -- already taken place in case a derived type inherits the pragma. 1840 -- The copy will be used as the foundation of the derived type's own 1841 -- version of the DIC assertion expression. 1842 1843 if Is_Tagged_Type (DIC_Typ) then 1844 Set_Expression_Copy (DIC_Arg, New_Copy_Tree (Expr)); 1845 end if; 1846 1847 -- If the pragma comes from an aspect specification, replace the 1848 -- saved expression because all type references must be substituted 1849 -- for the call to Preanalyze_Spec_Expression in Check_Aspect_At_xxx 1850 -- routines. 1851 1852 if Present (DIC_Asp) then 1853 Set_Entity (Identifier (DIC_Asp), New_Copy_Tree (Expr)); 1854 end if; 1855 1856 -- Once the DIC assertion expression is fully processed, add a check 1857 -- to the statements of the DIC procedure. 1858 1859 Add_DIC_Check 1860 (DIC_Prag => DIC_Prag, 1861 DIC_Expr => Expr, 1862 Stmts => Stmts); 1863 end Add_Own_DIC; 1864 1865 --------------------- 1866 -- Add_Parent_DICs -- 1867 --------------------- 1868 1869 procedure Add_Parent_DICs 1870 (T : Entity_Id; 1871 Obj_Id : Entity_Id; 1872 Checks : in out List_Id) 1873 is 1874 Dummy_1 : Entity_Id; 1875 Dummy_2 : Entity_Id; 1876 1877 Curr_Typ : Entity_Id; 1878 -- The entity of the current type being examined 1879 1880 Full_Typ : Entity_Id; 1881 -- The full view of Par_Typ 1882 1883 Par_Typ : Entity_Id; 1884 -- The entity of the parent type 1885 1886 Priv_Typ : Entity_Id; 1887 -- The partial view of Par_Typ 1888 1889 begin 1890 -- Climb the parent type chain 1891 1892 Curr_Typ := T; 1893 loop 1894 -- Do not consider subtypes, as they inherit the DICs from their 1895 -- base types. 1896 1897 Par_Typ := Base_Type (Etype (Base_Type (Curr_Typ))); 1898 1899 -- Stop the climb once the root of the parent chain is 1900 -- reached. 1901 1902 exit when Curr_Typ = Par_Typ; 1903 1904 -- Process the DICs of the parent type 1905 1906 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2); 1907 1908 -- Only try to inherit a DIC pragma from the parent type Par_Typ 1909 -- if it Has_Own_DIC pragma. The loop will proceed up the parent 1910 -- chain to find all types that have their own DIC. 1911 1912 if Has_Own_DIC (Par_Typ) then 1913 Add_Inherited_DICs 1914 (T => T, 1915 Priv_Typ => Priv_Typ, 1916 Full_Typ => Full_Typ, 1917 Obj_Id => Obj_Id, 1918 Checks => Checks); 1919 end if; 1920 1921 Curr_Typ := Par_Typ; 1922 end loop; 1923 end Add_Parent_DICs; 1924 1925 -- Local variables 1926 1927 Loc : constant Source_Ptr := Sloc (Typ); 1928 1929 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 1930 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 1931 -- Save the Ghost-related attributes to restore on exit 1932 1933 DIC_Prag : Node_Id; 1934 DIC_Typ : Entity_Id; 1935 Dummy_1 : Entity_Id; 1936 Dummy_2 : Entity_Id; 1937 Proc_Body : Node_Id; 1938 Proc_Body_Id : Entity_Id; 1939 Proc_Decl : Node_Id; 1940 Proc_Id : Entity_Id; 1941 Stmts : List_Id := No_List; 1942 1943 CRec_Typ : Entity_Id := Empty; 1944 -- The corresponding record type of Full_Typ 1945 1946 Full_Typ : Entity_Id := Empty; 1947 -- The full view of the working type 1948 1949 Obj_Id : Entity_Id := Empty; 1950 -- The _object formal parameter of the invariant procedure 1951 1952 Part_Proc : Entity_Id := Empty; 1953 -- The entity of the "partial" invariant procedure 1954 1955 Priv_Typ : Entity_Id := Empty; 1956 -- The partial view of the working type 1957 1958 Work_Typ : Entity_Id; 1959 -- The working type 1960 1961 -- Start of processing for Build_DIC_Procedure_Body 1962 1963 begin 1964 Work_Typ := Base_Type (Typ); 1965 1966 -- Do not process class-wide types as these are Itypes, but lack a first 1967 -- subtype (see below). 1968 1969 if Is_Class_Wide_Type (Work_Typ) then 1970 return; 1971 1972 -- Do not process the underlying full view of a private type. There is 1973 -- no way to get back to the partial view, plus the body will be built 1974 -- by the full view or the base type. 1975 1976 elsif Is_Underlying_Full_View (Work_Typ) then 1977 return; 1978 1979 -- Use the first subtype when dealing with various base types 1980 1981 elsif Is_Itype (Work_Typ) then 1982 Work_Typ := First_Subtype (Work_Typ); 1983 1984 -- The input denotes the corresponding record type of a protected or a 1985 -- task type. Work with the concurrent type because the corresponding 1986 -- record type may not be visible to clients of the type. 1987 1988 elsif Ekind (Work_Typ) = E_Record_Type 1989 and then Is_Concurrent_Record_Type (Work_Typ) 1990 then 1991 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 1992 end if; 1993 1994 -- The working type may be subject to pragma Ghost. Set the mode now to 1995 -- ensure that the DIC procedure is properly marked as Ghost. 1996 1997 Set_Ghost_Mode (Work_Typ); 1998 1999 -- The working type must be either define a DIC pragma of its own or 2000 -- inherit one from a parent type. 2001 2002 pragma Assert (Has_DIC (Work_Typ)); 2003 2004 -- Recover the type which defines the DIC pragma. This is either the 2005 -- working type itself or a parent type when the pragma is inherited. 2006 2007 DIC_Typ := Find_DIC_Type (Work_Typ); 2008 pragma Assert (Present (DIC_Typ)); 2009 2010 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition); 2011 pragma Assert (Present (DIC_Prag)); 2012 2013 -- Nothing to do if pragma DIC appears without an argument or its sole 2014 -- argument is "null". 2015 2016 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then 2017 goto Leave; 2018 end if; 2019 2020 -- Obtain both views of the type 2021 2022 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy_1, CRec_Typ); 2023 2024 -- The caller requests a body for the partial DIC procedure 2025 2026 if Partial_DIC then 2027 Proc_Id := Partial_DIC_Procedure (Work_Typ); 2028 2029 -- The "full" DIC procedure body was already created 2030 2031 -- Create a declaration for the "partial" DIC procedure if it 2032 -- is not available. 2033 2034 if No (Proc_Id) then 2035 Build_DIC_Procedure_Declaration 2036 (Typ => Work_Typ, 2037 Partial_DIC => True); 2038 2039 Proc_Id := Partial_DIC_Procedure (Work_Typ); 2040 end if; 2041 2042 -- The caller requests a body for the "full" DIC procedure 2043 2044 else 2045 Proc_Id := DIC_Procedure (Work_Typ); 2046 Part_Proc := Partial_DIC_Procedure (Work_Typ); 2047 2048 -- Create a declaration for the "full" DIC procedure if it is 2049 -- not available. 2050 2051 if No (Proc_Id) then 2052 Build_DIC_Procedure_Declaration (Work_Typ); 2053 Proc_Id := DIC_Procedure (Work_Typ); 2054 end if; 2055 end if; 2056 2057 -- At this point there should be a DIC procedure declaration 2058 2059 pragma Assert (Present (Proc_Id)); 2060 Proc_Decl := Unit_Declaration_Node (Proc_Id); 2061 2062 -- Nothing to do if the DIC procedure already has a body 2063 2064 if Present (Corresponding_Body (Proc_Decl)) then 2065 goto Leave; 2066 end if; 2067 2068 -- Emulate the environment of the DIC procedure by installing its scope 2069 -- and formal parameters. 2070 2071 Push_Scope (Proc_Id); 2072 Install_Formals (Proc_Id); 2073 2074 Obj_Id := First_Formal (Proc_Id); 2075 pragma Assert (Present (Obj_Id)); 2076 2077 -- The "partial" DIC procedure verifies the DICs of the partial view 2078 -- only. 2079 2080 if Partial_DIC then 2081 pragma Assert (Present (Priv_Typ)); 2082 2083 if Has_Own_DIC (Work_Typ) then -- If we're testing this then maybe 2084 Add_Own_DIC -- we shouldn't be calling Find_DIC_Typ above??? 2085 (DIC_Prag => DIC_Prag, 2086 DIC_Typ => DIC_Typ, -- Should this just be Work_Typ??? 2087 Obj_Id => Obj_Id, 2088 Stmts => Stmts); 2089 end if; 2090 2091 -- Otherwise the "full" DIC procedure verifies the DICs of the full 2092 -- view, well as DICs inherited from parent types. In addition, it 2093 -- indirectly verifies the DICs of the partial view by calling the 2094 -- "partial" DIC procedure. 2095 2096 else 2097 pragma Assert (Present (Full_Typ)); 2098 2099 -- Check the DIC of the partial view by calling the "partial" DIC 2100 -- procedure, unless the partial DIC body is empty. Generate: 2101 2102 -- <Work_Typ>Partial_DIC (_object); 2103 2104 if Present (Part_Proc) and then not Has_Null_Body (Part_Proc) then 2105 Append_New_To (Stmts, 2106 Make_Procedure_Call_Statement (Loc, 2107 Name => New_Occurrence_Of (Part_Proc, Loc), 2108 Parameter_Associations => New_List ( 2109 New_Occurrence_Of (Obj_Id, Loc)))); 2110 end if; 2111 2112 -- Derived subtypes do not have a partial view 2113 2114 if Present (Priv_Typ) then 2115 2116 -- The processing of the "full" DIC procedure intentionally 2117 -- skips the partial view because a) this may result in changes of 2118 -- visibility and b) lead to duplicate checks. However, when the 2119 -- full view is the underlying full view of an untagged derived 2120 -- type whose parent type is private, partial DICs appear on 2121 -- the rep item chain of the partial view only. 2122 2123 -- package Pack_1 is 2124 -- type Root ... is private; 2125 -- private 2126 -- <full view of Root> 2127 -- end Pack_1; 2128 2129 -- with Pack_1; 2130 -- package Pack_2 is 2131 -- type Child is new Pack_1.Root with Type_DIC => ...; 2132 -- <underlying full view of Child> 2133 -- end Pack_2; 2134 2135 -- As a result, the processing of the full view must also consider 2136 -- all DICs of the partial view. 2137 2138 if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then 2139 null; 2140 2141 -- Otherwise the DICs of the partial view are ignored 2142 2143 else 2144 -- Ignore the DICs of the partial view by eliminating the view 2145 2146 Priv_Typ := Empty; 2147 end if; 2148 end if; 2149 2150 -- Process inherited Default_Initial_Conditions for all parent types 2151 2152 Add_Parent_DICs (Work_Typ, Obj_Id, Stmts); 2153 end if; 2154 2155 End_Scope; 2156 2157 -- Produce an empty completing body in the following cases: 2158 -- * Assertions are disabled 2159 -- * The DIC Assertion_Policy is Ignore 2160 2161 if No (Stmts) then 2162 Stmts := New_List (Make_Null_Statement (Loc)); 2163 end if; 2164 2165 -- Generate: 2166 -- procedure <Work_Typ>DIC (_object : <Work_Typ>) is 2167 -- begin 2168 -- <Stmts> 2169 -- end <Work_Typ>DIC; 2170 2171 Proc_Body := 2172 Make_Subprogram_Body (Loc, 2173 Specification => 2174 Copy_Subprogram_Spec (Parent (Proc_Id)), 2175 Declarations => Empty_List, 2176 Handled_Statement_Sequence => 2177 Make_Handled_Sequence_Of_Statements (Loc, 2178 Statements => Stmts)); 2179 Proc_Body_Id := Defining_Entity (Proc_Body); 2180 2181 -- Perform minor decoration in case the body is not analyzed 2182 2183 Set_Ekind (Proc_Body_Id, E_Subprogram_Body); 2184 Set_Etype (Proc_Body_Id, Standard_Void_Type); 2185 Set_Scope (Proc_Body_Id, Current_Scope); 2186 Set_SPARK_Pragma (Proc_Body_Id, SPARK_Pragma (Proc_Id)); 2187 Set_SPARK_Pragma_Inherited 2188 (Proc_Body_Id, SPARK_Pragma_Inherited (Proc_Id)); 2189 2190 -- Link both spec and body to avoid generating duplicates 2191 2192 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id); 2193 Set_Corresponding_Spec (Proc_Body, Proc_Id); 2194 2195 -- The body should not be inserted into the tree when the context 2196 -- is a generic unit because it is not part of the template. 2197 -- Note that the body must still be generated in order to resolve the 2198 -- DIC assertion expression. 2199 2200 if Inside_A_Generic then 2201 null; 2202 2203 -- Semi-insert the body into the tree for GNATprove by setting its 2204 -- Parent field. This allows for proper upstream tree traversals. 2205 2206 elsif GNATprove_Mode then 2207 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ))); 2208 2209 -- Otherwise the body is part of the freezing actions of the working 2210 -- type. 2211 2212 else 2213 Append_Freeze_Action (Work_Typ, Proc_Body); 2214 end if; 2215 2216 <<Leave>> 2217 Restore_Ghost_Region (Saved_GM, Saved_IGR); 2218 end Build_DIC_Procedure_Body; 2219 2220 ------------------------------------- 2221 -- Build_DIC_Procedure_Declaration -- 2222 ------------------------------------- 2223 2224 -- WARNING: This routine manages Ghost regions. Return statements must be 2225 -- replaced by gotos which jump to the end of the routine and restore the 2226 -- Ghost mode. 2227 2228 procedure Build_DIC_Procedure_Declaration 2229 (Typ : Entity_Id; 2230 Partial_DIC : Boolean := False) 2231 is 2232 Loc : constant Source_Ptr := Sloc (Typ); 2233 2234 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 2235 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 2236 -- Save the Ghost-related attributes to restore on exit 2237 2238 DIC_Prag : Node_Id; 2239 DIC_Typ : Entity_Id; 2240 Proc_Decl : Node_Id; 2241 Proc_Id : Entity_Id; 2242 Proc_Nam : Name_Id; 2243 Typ_Decl : Node_Id; 2244 2245 CRec_Typ : Entity_Id; 2246 -- The corresponding record type of Full_Typ 2247 2248 Full_Typ : Entity_Id; 2249 -- The full view of working type 2250 2251 Obj_Id : Entity_Id; 2252 -- The _object formal parameter of the DIC procedure 2253 2254 Priv_Typ : Entity_Id; 2255 -- The partial view of working type 2256 2257 UFull_Typ : Entity_Id; 2258 -- The underlying full view of Full_Typ 2259 2260 Work_Typ : Entity_Id; 2261 -- The working type 2262 2263 begin 2264 Work_Typ := Base_Type (Typ); 2265 2266 -- Do not process class-wide types as these are Itypes, but lack a first 2267 -- subtype (see below). 2268 2269 if Is_Class_Wide_Type (Work_Typ) then 2270 return; 2271 2272 -- Do not process the underlying full view of a private type. There is 2273 -- no way to get back to the partial view, plus the body will be built 2274 -- by the full view or the base type. 2275 2276 elsif Is_Underlying_Full_View (Work_Typ) then 2277 return; 2278 2279 -- Use the first subtype when dealing with various base types 2280 2281 elsif Is_Itype (Work_Typ) then 2282 Work_Typ := First_Subtype (Work_Typ); 2283 2284 -- The input denotes the corresponding record type of a protected or a 2285 -- task type. Work with the concurrent type because the corresponding 2286 -- record type may not be visible to clients of the type. 2287 2288 elsif Ekind (Work_Typ) = E_Record_Type 2289 and then Is_Concurrent_Record_Type (Work_Typ) 2290 then 2291 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 2292 end if; 2293 2294 -- The working type may be subject to pragma Ghost. Set the mode now to 2295 -- ensure that the DIC procedure is properly marked as Ghost. 2296 2297 Set_Ghost_Mode (Work_Typ); 2298 2299 -- The type must be either subject to a DIC pragma or inherit one from a 2300 -- parent type. 2301 2302 pragma Assert (Has_DIC (Work_Typ)); 2303 2304 -- Recover the type which defines the DIC pragma. This is either the 2305 -- working type itself or a parent type when the pragma is inherited. 2306 2307 DIC_Typ := Find_DIC_Type (Work_Typ); 2308 pragma Assert (Present (DIC_Typ)); 2309 2310 DIC_Prag := Get_Pragma (DIC_Typ, Pragma_Default_Initial_Condition); 2311 pragma Assert (Present (DIC_Prag)); 2312 2313 -- Nothing to do if pragma DIC appears without an argument or its sole 2314 -- argument is "null". 2315 2316 if not Is_Verifiable_DIC_Pragma (DIC_Prag) then 2317 goto Leave; 2318 end if; 2319 2320 -- Nothing to do if the type already has a "partial" DIC procedure 2321 2322 if Partial_DIC then 2323 if Present (Partial_DIC_Procedure (Work_Typ)) then 2324 goto Leave; 2325 end if; 2326 2327 -- Nothing to do if the type already has a "full" DIC procedure 2328 2329 elsif Present (DIC_Procedure (Work_Typ)) then 2330 goto Leave; 2331 end if; 2332 2333 -- The caller requests the declaration of the "partial" DIC procedure 2334 2335 if Partial_DIC then 2336 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_DIC"); 2337 2338 -- Otherwise the caller requests the declaration of the "full" DIC 2339 -- procedure. 2340 2341 else 2342 Proc_Nam := New_External_Name (Chars (Work_Typ), "DIC"); 2343 end if; 2344 2345 Proc_Id := 2346 Make_Defining_Identifier (Loc, Chars => Proc_Nam); 2347 2348 -- Perform minor decoration in case the declaration is not analyzed 2349 2350 Set_Ekind (Proc_Id, E_Procedure); 2351 Set_Etype (Proc_Id, Standard_Void_Type); 2352 Set_Is_DIC_Procedure (Proc_Id); 2353 Set_Scope (Proc_Id, Current_Scope); 2354 Set_SPARK_Pragma (Proc_Id, SPARK_Mode_Pragma); 2355 Set_SPARK_Pragma_Inherited (Proc_Id); 2356 2357 Set_DIC_Procedure (Work_Typ, Proc_Id); 2358 2359 -- The DIC procedure requires debug info when the assertion expression 2360 -- is subject to Source Coverage Obligations. 2361 2362 if Generate_SCO then 2363 Set_Debug_Info_Needed (Proc_Id); 2364 end if; 2365 2366 -- Obtain all views of the input type 2367 2368 Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ); 2369 2370 -- Associate the DIC procedure and various flags with all views 2371 2372 Propagate_DIC_Attributes (Priv_Typ, From_Typ => Work_Typ); 2373 Propagate_DIC_Attributes (Full_Typ, From_Typ => Work_Typ); 2374 Propagate_DIC_Attributes (UFull_Typ, From_Typ => Work_Typ); 2375 Propagate_DIC_Attributes (CRec_Typ, From_Typ => Work_Typ); 2376 2377 -- The declaration of the DIC procedure must be inserted after the 2378 -- declaration of the partial view as this allows for proper external 2379 -- visibility. 2380 2381 if Present (Priv_Typ) then 2382 Typ_Decl := Declaration_Node (Priv_Typ); 2383 2384 -- Derived types with the full view as parent do not have a partial 2385 -- view. Insert the DIC procedure after the derived type. 2386 2387 else 2388 Typ_Decl := Declaration_Node (Full_Typ); 2389 end if; 2390 2391 -- The type should have a declarative node 2392 2393 pragma Assert (Present (Typ_Decl)); 2394 2395 -- Create the formal parameter which emulates the variable-like behavior 2396 -- of the type's current instance. 2397 2398 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject); 2399 2400 -- Perform minor decoration in case the declaration is not analyzed 2401 2402 Set_Ekind (Obj_Id, E_In_Parameter); 2403 Set_Etype (Obj_Id, Work_Typ); 2404 Set_Scope (Obj_Id, Proc_Id); 2405 2406 Set_First_Entity (Proc_Id, Obj_Id); 2407 Set_Last_Entity (Proc_Id, Obj_Id); 2408 2409 -- Generate: 2410 -- procedure <Work_Typ>DIC (_object : <Work_Typ>); 2411 2412 Proc_Decl := 2413 Make_Subprogram_Declaration (Loc, 2414 Specification => 2415 Make_Procedure_Specification (Loc, 2416 Defining_Unit_Name => Proc_Id, 2417 Parameter_Specifications => New_List ( 2418 Make_Parameter_Specification (Loc, 2419 Defining_Identifier => Obj_Id, 2420 Parameter_Type => 2421 New_Occurrence_Of (Work_Typ, Loc))))); 2422 2423 -- The declaration should not be inserted into the tree when the context 2424 -- is a generic unit because it is not part of the template. 2425 2426 if Inside_A_Generic then 2427 null; 2428 2429 -- Semi-insert the declaration into the tree for GNATprove by setting 2430 -- its Parent field. This allows for proper upstream tree traversals. 2431 2432 elsif GNATprove_Mode then 2433 Set_Parent (Proc_Decl, Parent (Typ_Decl)); 2434 2435 -- Otherwise insert the declaration 2436 2437 else 2438 Insert_After_And_Analyze (Typ_Decl, Proc_Decl); 2439 end if; 2440 2441 <<Leave>> 2442 Restore_Ghost_Region (Saved_GM, Saved_IGR); 2443 end Build_DIC_Procedure_Declaration; 2444 2445 ------------------------------------ 2446 -- Build_Invariant_Procedure_Body -- 2447 ------------------------------------ 2448 2449 -- WARNING: This routine manages Ghost regions. Return statements must be 2450 -- replaced by gotos which jump to the end of the routine and restore the 2451 -- Ghost mode. 2452 2453 procedure Build_Invariant_Procedure_Body 2454 (Typ : Entity_Id; 2455 Partial_Invariant : Boolean := False) 2456 is 2457 Loc : constant Source_Ptr := Sloc (Typ); 2458 2459 Pragmas_Seen : Elist_Id := No_Elist; 2460 -- This list contains all invariant pragmas processed so far. The list 2461 -- is used to avoid generating redundant invariant checks. 2462 2463 Produced_Check : Boolean := False; 2464 -- This flag tracks whether the type has produced at least one invariant 2465 -- check. The flag is used as a sanity check at the end of the routine. 2466 2467 -- NOTE: most of the routines in Build_Invariant_Procedure_Body are 2468 -- intentionally unnested to avoid deep indentation of code. 2469 2470 -- NOTE: all Add_xxx_Invariants routines are reactive. In other words 2471 -- they emit checks, loops (for arrays) and case statements (for record 2472 -- variant parts) only when there are invariants to verify. This keeps 2473 -- the body of the invariant procedure free of useless code. 2474 2475 procedure Add_Array_Component_Invariants 2476 (T : Entity_Id; 2477 Obj_Id : Entity_Id; 2478 Checks : in out List_Id); 2479 -- Generate an invariant check for each component of array type T. 2480 -- Obj_Id denotes the entity of the _object formal parameter of the 2481 -- invariant procedure. All created checks are added to list Checks. 2482 2483 procedure Add_Inherited_Invariants 2484 (T : Entity_Id; 2485 Priv_Typ : Entity_Id; 2486 Full_Typ : Entity_Id; 2487 Obj_Id : Entity_Id; 2488 Checks : in out List_Id); 2489 -- Generate an invariant check for each inherited class-wide invariant 2490 -- coming from all parent types of type T. Priv_Typ and Full_Typ denote 2491 -- the partial and full view of the parent type. Obj_Id denotes the 2492 -- entity of the _object formal parameter of the invariant procedure. 2493 -- All created checks are added to list Checks. 2494 2495 procedure Add_Interface_Invariants 2496 (T : Entity_Id; 2497 Obj_Id : Entity_Id; 2498 Checks : in out List_Id); 2499 -- Generate an invariant check for each inherited class-wide invariant 2500 -- coming from all interfaces implemented by type T. Obj_Id denotes the 2501 -- entity of the _object formal parameter of the invariant procedure. 2502 -- All created checks are added to list Checks. 2503 2504 procedure Add_Invariant_Check 2505 (Prag : Node_Id; 2506 Expr : Node_Id; 2507 Checks : in out List_Id; 2508 Inherited : Boolean := False); 2509 -- Subsidiary to all Add_xxx_Invariant routines. Add a runtime check to 2510 -- verify assertion expression Expr of pragma Prag. All generated code 2511 -- is added to list Checks. Flag Inherited should be set when the pragma 2512 -- is inherited from a parent or interface type. 2513 2514 procedure Add_Own_Invariants 2515 (T : Entity_Id; 2516 Obj_Id : Entity_Id; 2517 Checks : in out List_Id; 2518 Priv_Item : Node_Id := Empty); 2519 -- Generate an invariant check for each invariant found for type T. 2520 -- Obj_Id denotes the entity of the _object formal parameter of the 2521 -- invariant procedure. All created checks are added to list Checks. 2522 -- Priv_Item denotes the first rep item of the private type. 2523 2524 procedure Add_Parent_Invariants 2525 (T : Entity_Id; 2526 Obj_Id : Entity_Id; 2527 Checks : in out List_Id); 2528 -- Generate an invariant check for each inherited class-wide invariant 2529 -- coming from all parent types of type T. Obj_Id denotes the entity of 2530 -- the _object formal parameter of the invariant procedure. All created 2531 -- checks are added to list Checks. 2532 2533 procedure Add_Record_Component_Invariants 2534 (T : Entity_Id; 2535 Obj_Id : Entity_Id; 2536 Checks : in out List_Id); 2537 -- Generate an invariant check for each component of record type T. 2538 -- Obj_Id denotes the entity of the _object formal parameter of the 2539 -- invariant procedure. All created checks are added to list Checks. 2540 2541 ------------------------------------ 2542 -- Add_Array_Component_Invariants -- 2543 ------------------------------------ 2544 2545 procedure Add_Array_Component_Invariants 2546 (T : Entity_Id; 2547 Obj_Id : Entity_Id; 2548 Checks : in out List_Id) 2549 is 2550 Comp_Typ : constant Entity_Id := Component_Type (T); 2551 Dims : constant Pos := Number_Dimensions (T); 2552 2553 procedure Process_Array_Component 2554 (Indices : List_Id; 2555 Comp_Checks : in out List_Id); 2556 -- Generate an invariant check for an array component identified by 2557 -- the indices in list Indices. All created checks are added to list 2558 -- Comp_Checks. 2559 2560 procedure Process_One_Dimension 2561 (Dim : Pos; 2562 Indices : List_Id; 2563 Dim_Checks : in out List_Id); 2564 -- Generate a loop over the Nth dimension Dim of an array type. List 2565 -- Indices contains all array indices for the dimension. All created 2566 -- checks are added to list Dim_Checks. 2567 2568 ----------------------------- 2569 -- Process_Array_Component -- 2570 ----------------------------- 2571 2572 procedure Process_Array_Component 2573 (Indices : List_Id; 2574 Comp_Checks : in out List_Id) 2575 is 2576 Proc_Id : Entity_Id; 2577 2578 begin 2579 if Has_Invariants (Comp_Typ) then 2580 2581 -- In GNATprove mode, the component invariants are checked by 2582 -- other means. They should not be added to the array type 2583 -- invariant procedure, so that the procedure can be used to 2584 -- check the array type invariants if any. 2585 2586 if GNATprove_Mode then 2587 null; 2588 2589 else 2590 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ)); 2591 2592 -- The component type should have an invariant procedure 2593 -- if it has invariants of its own or inherits class-wide 2594 -- invariants from parent or interface types. 2595 2596 pragma Assert (Present (Proc_Id)); 2597 2598 -- Generate: 2599 -- <Comp_Typ>Invariant (_object (<Indices>)); 2600 2601 -- The invariant procedure has a null body if assertions are 2602 -- disabled or Assertion_Policy Ignore is in effect. 2603 2604 if not Has_Null_Body (Proc_Id) then 2605 Append_New_To (Comp_Checks, 2606 Make_Procedure_Call_Statement (Loc, 2607 Name => 2608 New_Occurrence_Of (Proc_Id, Loc), 2609 Parameter_Associations => New_List ( 2610 Make_Indexed_Component (Loc, 2611 Prefix => New_Occurrence_Of (Obj_Id, Loc), 2612 Expressions => New_Copy_List (Indices))))); 2613 end if; 2614 end if; 2615 2616 Produced_Check := True; 2617 end if; 2618 end Process_Array_Component; 2619 2620 --------------------------- 2621 -- Process_One_Dimension -- 2622 --------------------------- 2623 2624 procedure Process_One_Dimension 2625 (Dim : Pos; 2626 Indices : List_Id; 2627 Dim_Checks : in out List_Id) 2628 is 2629 Comp_Checks : List_Id := No_List; 2630 Index : Entity_Id; 2631 2632 begin 2633 -- Generate the invariant checks for the array component after all 2634 -- dimensions have produced their respective loops. 2635 2636 if Dim > Dims then 2637 Process_Array_Component 2638 (Indices => Indices, 2639 Comp_Checks => Dim_Checks); 2640 2641 -- Otherwise create a loop for the current dimension 2642 2643 else 2644 -- Create a new loop variable for each dimension 2645 2646 Index := 2647 Make_Defining_Identifier (Loc, 2648 Chars => New_External_Name ('I', Dim)); 2649 Append_To (Indices, New_Occurrence_Of (Index, Loc)); 2650 2651 Process_One_Dimension 2652 (Dim => Dim + 1, 2653 Indices => Indices, 2654 Dim_Checks => Comp_Checks); 2655 2656 -- Generate: 2657 -- for I<Dim> in _object'Range (<Dim>) loop 2658 -- <Comp_Checks> 2659 -- end loop; 2660 2661 -- Note that the invariant procedure may have a null body if 2662 -- assertions are disabled or Assertion_Policy Ignore is in 2663 -- effect. 2664 2665 if Present (Comp_Checks) then 2666 Append_New_To (Dim_Checks, 2667 Make_Implicit_Loop_Statement (T, 2668 Identifier => Empty, 2669 Iteration_Scheme => 2670 Make_Iteration_Scheme (Loc, 2671 Loop_Parameter_Specification => 2672 Make_Loop_Parameter_Specification (Loc, 2673 Defining_Identifier => Index, 2674 Discrete_Subtype_Definition => 2675 Make_Attribute_Reference (Loc, 2676 Prefix => 2677 New_Occurrence_Of (Obj_Id, Loc), 2678 Attribute_Name => Name_Range, 2679 Expressions => New_List ( 2680 Make_Integer_Literal (Loc, Dim))))), 2681 Statements => Comp_Checks)); 2682 end if; 2683 end if; 2684 end Process_One_Dimension; 2685 2686 -- Start of processing for Add_Array_Component_Invariants 2687 2688 begin 2689 Process_One_Dimension 2690 (Dim => 1, 2691 Indices => New_List, 2692 Dim_Checks => Checks); 2693 end Add_Array_Component_Invariants; 2694 2695 ------------------------------ 2696 -- Add_Inherited_Invariants -- 2697 ------------------------------ 2698 2699 procedure Add_Inherited_Invariants 2700 (T : Entity_Id; 2701 Priv_Typ : Entity_Id; 2702 Full_Typ : Entity_Id; 2703 Obj_Id : Entity_Id; 2704 Checks : in out List_Id) 2705 is 2706 Deriv_Typ : Entity_Id; 2707 Expr : Node_Id; 2708 Prag : Node_Id; 2709 Prag_Expr : Node_Id; 2710 Prag_Expr_Arg : Node_Id; 2711 Prag_Typ : Node_Id; 2712 Prag_Typ_Arg : Node_Id; 2713 2714 Par_Proc : Entity_Id; 2715 -- The "partial" invariant procedure of Par_Typ 2716 2717 Par_Typ : Entity_Id; 2718 -- The suitable view of the parent type used in the substitution of 2719 -- type attributes. 2720 2721 begin 2722 if not Present (Priv_Typ) and then not Present (Full_Typ) then 2723 return; 2724 end if; 2725 2726 -- When the type inheriting the class-wide invariant is a concurrent 2727 -- type, use the corresponding record type because it contains all 2728 -- primitive operations of the concurrent type and allows for proper 2729 -- substitution. 2730 2731 if Is_Concurrent_Type (T) then 2732 Deriv_Typ := Corresponding_Record_Type (T); 2733 else 2734 Deriv_Typ := T; 2735 end if; 2736 2737 pragma Assert (Present (Deriv_Typ)); 2738 2739 -- Determine which rep item chain to use. Precedence is given to that 2740 -- of the parent type's partial view since it usually carries all the 2741 -- class-wide invariants. 2742 2743 if Present (Priv_Typ) then 2744 Prag := First_Rep_Item (Priv_Typ); 2745 else 2746 Prag := First_Rep_Item (Full_Typ); 2747 end if; 2748 2749 while Present (Prag) loop 2750 if Nkind (Prag) = N_Pragma 2751 and then Pragma_Name (Prag) = Name_Invariant 2752 then 2753 -- Nothing to do if the pragma was already processed 2754 2755 if Contains (Pragmas_Seen, Prag) then 2756 return; 2757 2758 -- Nothing to do when the caller requests the processing of all 2759 -- inherited class-wide invariants, but the pragma does not 2760 -- fall in this category. 2761 2762 elsif not Class_Present (Prag) then 2763 return; 2764 end if; 2765 2766 -- Extract the arguments of the invariant pragma 2767 2768 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag)); 2769 Prag_Expr_Arg := Next (Prag_Typ_Arg); 2770 Prag_Expr := Expression_Copy (Prag_Expr_Arg); 2771 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg); 2772 2773 -- The pragma applies to the partial view of the parent type 2774 2775 if Present (Priv_Typ) 2776 and then Entity (Prag_Typ) = Priv_Typ 2777 then 2778 Par_Typ := Priv_Typ; 2779 2780 -- The pragma applies to the full view of the parent type 2781 2782 elsif Present (Full_Typ) 2783 and then Entity (Prag_Typ) = Full_Typ 2784 then 2785 Par_Typ := Full_Typ; 2786 2787 -- Otherwise the pragma does not belong to the parent type and 2788 -- should not be considered. 2789 2790 else 2791 return; 2792 end if; 2793 2794 -- Perform the following substitutions: 2795 2796 -- * Replace a reference to the _object parameter of the 2797 -- parent type's partial invariant procedure with a 2798 -- reference to the _object parameter of the derived 2799 -- type's full invariant procedure. 2800 2801 -- * Replace a reference to a discriminant of the parent type 2802 -- with a suitable value from the point of view of the 2803 -- derived type. 2804 2805 -- * Replace a call to an overridden parent primitive with a 2806 -- call to the overriding derived type primitive. 2807 2808 -- * Replace a call to an inherited parent primitive with a 2809 -- call to the internally-generated inherited derived type 2810 -- primitive. 2811 2812 Expr := New_Copy_Tree (Prag_Expr); 2813 2814 -- The parent type must have a "partial" invariant procedure 2815 -- because class-wide invariants are captured exclusively by 2816 -- it. 2817 2818 Par_Proc := Partial_Invariant_Procedure (Par_Typ); 2819 pragma Assert (Present (Par_Proc)); 2820 2821 Replace_References 2822 (Expr => Expr, 2823 Par_Typ => Par_Typ, 2824 Deriv_Typ => Deriv_Typ, 2825 Par_Obj => First_Formal (Par_Proc), 2826 Deriv_Obj => Obj_Id); 2827 2828 Add_Invariant_Check (Prag, Expr, Checks, Inherited => True); 2829 end if; 2830 2831 Next_Rep_Item (Prag); 2832 end loop; 2833 end Add_Inherited_Invariants; 2834 2835 ------------------------------ 2836 -- Add_Interface_Invariants -- 2837 ------------------------------ 2838 2839 procedure Add_Interface_Invariants 2840 (T : Entity_Id; 2841 Obj_Id : Entity_Id; 2842 Checks : in out List_Id) 2843 is 2844 Iface_Elmt : Elmt_Id; 2845 Ifaces : Elist_Id; 2846 2847 begin 2848 -- Generate an invariant check for each class-wide invariant coming 2849 -- from all interfaces implemented by type T. 2850 2851 if Is_Tagged_Type (T) then 2852 Collect_Interfaces (T, Ifaces); 2853 2854 -- Process the class-wide invariants of all implemented interfaces 2855 2856 Iface_Elmt := First_Elmt (Ifaces); 2857 while Present (Iface_Elmt) loop 2858 2859 -- The Full_Typ parameter is intentionally left Empty because 2860 -- interfaces are treated as the partial view of a private type 2861 -- in order to achieve uniformity with the general case. 2862 2863 Add_Inherited_Invariants 2864 (T => T, 2865 Priv_Typ => Node (Iface_Elmt), 2866 Full_Typ => Empty, 2867 Obj_Id => Obj_Id, 2868 Checks => Checks); 2869 2870 Next_Elmt (Iface_Elmt); 2871 end loop; 2872 end if; 2873 end Add_Interface_Invariants; 2874 2875 ------------------------- 2876 -- Add_Invariant_Check -- 2877 ------------------------- 2878 2879 procedure Add_Invariant_Check 2880 (Prag : Node_Id; 2881 Expr : Node_Id; 2882 Checks : in out List_Id; 2883 Inherited : Boolean := False) 2884 is 2885 Args : constant List_Id := Pragma_Argument_Associations (Prag); 2886 Nam : constant Name_Id := Original_Aspect_Pragma_Name (Prag); 2887 Ploc : constant Source_Ptr := Sloc (Prag); 2888 Str_Arg : constant Node_Id := Next (Next (First (Args))); 2889 2890 Assoc : List_Id; 2891 Str : String_Id; 2892 2893 begin 2894 -- The invariant is ignored, nothing left to do 2895 2896 if Is_Ignored (Prag) then 2897 null; 2898 2899 -- Otherwise the invariant is checked. Build a pragma Check to verify 2900 -- the expression at run time. 2901 2902 else 2903 Assoc := New_List ( 2904 Make_Pragma_Argument_Association (Ploc, 2905 Expression => Make_Identifier (Ploc, Nam)), 2906 Make_Pragma_Argument_Association (Ploc, 2907 Expression => Expr)); 2908 2909 -- Handle the String argument (if any) 2910 2911 if Present (Str_Arg) then 2912 Str := Strval (Get_Pragma_Arg (Str_Arg)); 2913 2914 -- When inheriting an invariant, modify the message from 2915 -- "failed invariant" to "failed inherited invariant". 2916 2917 if Inherited then 2918 String_To_Name_Buffer (Str); 2919 2920 if Name_Buffer (1 .. 16) = "failed invariant" then 2921 Insert_Str_In_Name_Buffer ("inherited ", 8); 2922 Str := String_From_Name_Buffer; 2923 end if; 2924 end if; 2925 2926 Append_To (Assoc, 2927 Make_Pragma_Argument_Association (Ploc, 2928 Expression => Make_String_Literal (Ploc, Str))); 2929 end if; 2930 2931 -- Generate: 2932 -- pragma Check (<Nam>, <Expr>, <Str>); 2933 2934 Append_New_To (Checks, 2935 Make_Pragma (Ploc, 2936 Chars => Name_Check, 2937 Pragma_Argument_Associations => Assoc)); 2938 end if; 2939 2940 -- Output an info message when inheriting an invariant and the 2941 -- listing option is enabled. 2942 2943 if Inherited and Opt.List_Inherited_Aspects then 2944 Error_Msg_Sloc := Sloc (Prag); 2945 Error_Msg_N 2946 ("info: & inherits `Invariant''Class` aspect from #?L?", Typ); 2947 end if; 2948 2949 -- Add the pragma to the list of processed pragmas 2950 2951 Append_New_Elmt (Prag, Pragmas_Seen); 2952 Produced_Check := True; 2953 end Add_Invariant_Check; 2954 2955 --------------------------- 2956 -- Add_Parent_Invariants -- 2957 --------------------------- 2958 2959 procedure Add_Parent_Invariants 2960 (T : Entity_Id; 2961 Obj_Id : Entity_Id; 2962 Checks : in out List_Id) 2963 is 2964 Dummy_1 : Entity_Id; 2965 Dummy_2 : Entity_Id; 2966 2967 Curr_Typ : Entity_Id; 2968 -- The entity of the current type being examined 2969 2970 Full_Typ : Entity_Id; 2971 -- The full view of Par_Typ 2972 2973 Par_Typ : Entity_Id; 2974 -- The entity of the parent type 2975 2976 Priv_Typ : Entity_Id; 2977 -- The partial view of Par_Typ 2978 2979 begin 2980 -- Do not process array types because they cannot have true parent 2981 -- types. This also prevents the generation of a duplicate invariant 2982 -- check when the input type is an array base type because its Etype 2983 -- denotes the first subtype, both of which share the same component 2984 -- type. 2985 2986 if Is_Array_Type (T) then 2987 return; 2988 end if; 2989 2990 -- Climb the parent type chain 2991 2992 Curr_Typ := T; 2993 loop 2994 -- Do not consider subtypes as they inherit the invariants 2995 -- from their base types. 2996 2997 Par_Typ := Base_Type (Etype (Curr_Typ)); 2998 2999 -- Stop the climb once the root of the parent chain is 3000 -- reached. 3001 3002 exit when Curr_Typ = Par_Typ; 3003 3004 -- Process the class-wide invariants of the parent type 3005 3006 Get_Views (Par_Typ, Priv_Typ, Full_Typ, Dummy_1, Dummy_2); 3007 3008 -- Process the elements of an array type 3009 3010 if Is_Array_Type (Full_Typ) then 3011 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Checks); 3012 3013 -- Process the components of a record type 3014 3015 elsif Ekind (Full_Typ) = E_Record_Type then 3016 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Checks); 3017 end if; 3018 3019 Add_Inherited_Invariants 3020 (T => T, 3021 Priv_Typ => Priv_Typ, 3022 Full_Typ => Full_Typ, 3023 Obj_Id => Obj_Id, 3024 Checks => Checks); 3025 3026 Curr_Typ := Par_Typ; 3027 end loop; 3028 end Add_Parent_Invariants; 3029 3030 ------------------------ 3031 -- Add_Own_Invariants -- 3032 ------------------------ 3033 3034 procedure Add_Own_Invariants 3035 (T : Entity_Id; 3036 Obj_Id : Entity_Id; 3037 Checks : in out List_Id; 3038 Priv_Item : Node_Id := Empty) 3039 is 3040 Expr : Node_Id; 3041 Prag : Node_Id; 3042 Prag_Asp : Node_Id; 3043 Prag_Expr : Node_Id; 3044 Prag_Expr_Arg : Node_Id; 3045 Prag_Typ : Node_Id; 3046 Prag_Typ_Arg : Node_Id; 3047 3048 begin 3049 if not Present (T) then 3050 return; 3051 end if; 3052 3053 Prag := First_Rep_Item (T); 3054 while Present (Prag) loop 3055 if Nkind (Prag) = N_Pragma 3056 and then Pragma_Name (Prag) = Name_Invariant 3057 then 3058 -- Stop the traversal of the rep item chain once a specific 3059 -- item is encountered. 3060 3061 if Present (Priv_Item) and then Prag = Priv_Item then 3062 exit; 3063 end if; 3064 3065 -- Nothing to do if the pragma was already processed 3066 3067 if Contains (Pragmas_Seen, Prag) then 3068 return; 3069 end if; 3070 3071 -- Extract the arguments of the invariant pragma 3072 3073 Prag_Typ_Arg := First (Pragma_Argument_Associations (Prag)); 3074 Prag_Expr_Arg := Next (Prag_Typ_Arg); 3075 Prag_Expr := Get_Pragma_Arg (Prag_Expr_Arg); 3076 Prag_Typ := Get_Pragma_Arg (Prag_Typ_Arg); 3077 Prag_Asp := Corresponding_Aspect (Prag); 3078 3079 -- Verify the pragma belongs to T, otherwise the pragma applies 3080 -- to a parent type in which case it will be processed later by 3081 -- Add_Parent_Invariants or Add_Interface_Invariants. 3082 3083 if Entity (Prag_Typ) /= T then 3084 return; 3085 end if; 3086 3087 Expr := New_Copy_Tree (Prag_Expr); 3088 3089 -- Substitute all references to type T with references to the 3090 -- _object formal parameter. 3091 3092 Replace_Type_References (Expr, T, Obj_Id); 3093 3094 -- Preanalyze the invariant expression to detect errors and at 3095 -- the same time capture the visibility of the proper package 3096 -- part. 3097 3098 Set_Parent (Expr, Parent (Prag_Expr)); 3099 Preanalyze_Assert_Expression (Expr, Any_Boolean); 3100 3101 -- Save a copy of the expression when T is tagged to detect 3102 -- errors and capture the visibility of the proper package part 3103 -- for the generation of inherited type invariants. 3104 3105 if Is_Tagged_Type (T) then 3106 Set_Expression_Copy (Prag_Expr_Arg, New_Copy_Tree (Expr)); 3107 end if; 3108 3109 -- If the pragma comes from an aspect specification, replace 3110 -- the saved expression because all type references must be 3111 -- substituted for the call to Preanalyze_Spec_Expression in 3112 -- Check_Aspect_At_xxx routines. 3113 3114 if Present (Prag_Asp) then 3115 Set_Entity (Identifier (Prag_Asp), New_Copy_Tree (Expr)); 3116 end if; 3117 3118 Add_Invariant_Check (Prag, Expr, Checks); 3119 end if; 3120 3121 Next_Rep_Item (Prag); 3122 end loop; 3123 end Add_Own_Invariants; 3124 3125 ------------------------------------- 3126 -- Add_Record_Component_Invariants -- 3127 ------------------------------------- 3128 3129 procedure Add_Record_Component_Invariants 3130 (T : Entity_Id; 3131 Obj_Id : Entity_Id; 3132 Checks : in out List_Id) 3133 is 3134 procedure Process_Component_List 3135 (Comp_List : Node_Id; 3136 CL_Checks : in out List_Id); 3137 -- Generate invariant checks for all record components found in 3138 -- component list Comp_List, including variant parts. All created 3139 -- checks are added to list CL_Checks. 3140 3141 procedure Process_Record_Component 3142 (Comp_Id : Entity_Id; 3143 Comp_Checks : in out List_Id); 3144 -- Generate an invariant check for a record component identified by 3145 -- Comp_Id. All created checks are added to list Comp_Checks. 3146 3147 ---------------------------- 3148 -- Process_Component_List -- 3149 ---------------------------- 3150 3151 procedure Process_Component_List 3152 (Comp_List : Node_Id; 3153 CL_Checks : in out List_Id) 3154 is 3155 Comp : Node_Id; 3156 Var : Node_Id; 3157 Var_Alts : List_Id := No_List; 3158 Var_Checks : List_Id := No_List; 3159 Var_Stmts : List_Id; 3160 3161 Produced_Variant_Check : Boolean := False; 3162 -- This flag tracks whether the component has produced at least 3163 -- one invariant check. 3164 3165 begin 3166 -- Traverse the component items 3167 3168 Comp := First (Component_Items (Comp_List)); 3169 while Present (Comp) loop 3170 if Nkind (Comp) = N_Component_Declaration then 3171 3172 -- Generate the component invariant check 3173 3174 Process_Record_Component 3175 (Comp_Id => Defining_Entity (Comp), 3176 Comp_Checks => CL_Checks); 3177 end if; 3178 3179 Next (Comp); 3180 end loop; 3181 3182 -- Traverse the variant part 3183 3184 if Present (Variant_Part (Comp_List)) then 3185 Var := First (Variants (Variant_Part (Comp_List))); 3186 while Present (Var) loop 3187 Var_Checks := No_List; 3188 3189 -- Generate invariant checks for all components and variant 3190 -- parts that qualify. 3191 3192 Process_Component_List 3193 (Comp_List => Component_List (Var), 3194 CL_Checks => Var_Checks); 3195 3196 -- The components of the current variant produced at least 3197 -- one invariant check. 3198 3199 if Present (Var_Checks) then 3200 Var_Stmts := Var_Checks; 3201 Produced_Variant_Check := True; 3202 3203 -- Otherwise there are either no components with invariants, 3204 -- assertions are disabled, or Assertion_Policy Ignore is in 3205 -- effect. 3206 3207 else 3208 Var_Stmts := New_List (Make_Null_Statement (Loc)); 3209 end if; 3210 3211 Append_New_To (Var_Alts, 3212 Make_Case_Statement_Alternative (Loc, 3213 Discrete_Choices => 3214 New_Copy_List (Discrete_Choices (Var)), 3215 Statements => Var_Stmts)); 3216 3217 Next (Var); 3218 end loop; 3219 3220 -- Create a case statement which verifies the invariant checks 3221 -- of a particular component list depending on the discriminant 3222 -- values only when there is at least one real invariant check. 3223 3224 if Produced_Variant_Check then 3225 Append_New_To (CL_Checks, 3226 Make_Case_Statement (Loc, 3227 Expression => 3228 Make_Selected_Component (Loc, 3229 Prefix => New_Occurrence_Of (Obj_Id, Loc), 3230 Selector_Name => 3231 New_Occurrence_Of 3232 (Entity (Name (Variant_Part (Comp_List))), Loc)), 3233 Alternatives => Var_Alts)); 3234 end if; 3235 end if; 3236 end Process_Component_List; 3237 3238 ------------------------------ 3239 -- Process_Record_Component -- 3240 ------------------------------ 3241 3242 procedure Process_Record_Component 3243 (Comp_Id : Entity_Id; 3244 Comp_Checks : in out List_Id) 3245 is 3246 Comp_Typ : constant Entity_Id := Etype (Comp_Id); 3247 Proc_Id : Entity_Id; 3248 3249 Produced_Component_Check : Boolean := False; 3250 -- This flag tracks whether the component has produced at least 3251 -- one invariant check. 3252 3253 begin 3254 -- Nothing to do for internal component _parent. Note that it is 3255 -- not desirable to check whether the component comes from source 3256 -- because protected type components are relocated to an internal 3257 -- corresponding record, but still need processing. 3258 3259 if Chars (Comp_Id) = Name_uParent then 3260 return; 3261 end if; 3262 3263 -- Verify the invariant of the component. Note that an access 3264 -- type may have an invariant when it acts as the full view of a 3265 -- private type and the invariant appears on the partial view. In 3266 -- this case verify the access value itself. 3267 3268 if Has_Invariants (Comp_Typ) then 3269 3270 -- In GNATprove mode, the component invariants are checked by 3271 -- other means. They should not be added to the record type 3272 -- invariant procedure, so that the procedure can be used to 3273 -- check the record type invariants if any. 3274 3275 if GNATprove_Mode then 3276 null; 3277 3278 else 3279 Proc_Id := Invariant_Procedure (Base_Type (Comp_Typ)); 3280 3281 -- The component type should have an invariant procedure 3282 -- if it has invariants of its own or inherits class-wide 3283 -- invariants from parent or interface types. 3284 3285 pragma Assert (Present (Proc_Id)); 3286 3287 -- Generate: 3288 -- <Comp_Typ>Invariant (T (_object).<Comp_Id>); 3289 3290 -- Note that the invariant procedure may have a null body if 3291 -- assertions are disabled or Assertion_Policy Ignore is in 3292 -- effect. 3293 3294 if not Has_Null_Body (Proc_Id) then 3295 Append_New_To (Comp_Checks, 3296 Make_Procedure_Call_Statement (Loc, 3297 Name => 3298 New_Occurrence_Of (Proc_Id, Loc), 3299 Parameter_Associations => New_List ( 3300 Make_Selected_Component (Loc, 3301 Prefix => 3302 Unchecked_Convert_To 3303 (T, New_Occurrence_Of (Obj_Id, Loc)), 3304 Selector_Name => 3305 New_Occurrence_Of (Comp_Id, Loc))))); 3306 end if; 3307 end if; 3308 3309 Produced_Check := True; 3310 Produced_Component_Check := True; 3311 end if; 3312 3313 if Produced_Component_Check and then Has_Unchecked_Union (T) then 3314 Error_Msg_NE 3315 ("invariants cannot be checked on components of " 3316 & "unchecked_union type &??", Comp_Id, T); 3317 end if; 3318 end Process_Record_Component; 3319 3320 -- Local variables 3321 3322 Comps : Node_Id; 3323 Def : Node_Id; 3324 3325 -- Start of processing for Add_Record_Component_Invariants 3326 3327 begin 3328 -- An untagged derived type inherits the components of its parent 3329 -- type. In order to avoid creating redundant invariant checks, do 3330 -- not process the components now. Instead wait until the ultimate 3331 -- parent of the untagged derivation chain is reached. 3332 3333 if not Is_Untagged_Derivation (T) then 3334 Def := Type_Definition (Parent (T)); 3335 3336 if Nkind (Def) = N_Derived_Type_Definition then 3337 Def := Record_Extension_Part (Def); 3338 end if; 3339 3340 pragma Assert (Nkind (Def) = N_Record_Definition); 3341 Comps := Component_List (Def); 3342 3343 if Present (Comps) then 3344 Process_Component_List 3345 (Comp_List => Comps, 3346 CL_Checks => Checks); 3347 end if; 3348 end if; 3349 end Add_Record_Component_Invariants; 3350 3351 -- Local variables 3352 3353 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 3354 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 3355 -- Save the Ghost-related attributes to restore on exit 3356 3357 Dummy : Entity_Id; 3358 Priv_Item : Node_Id; 3359 Proc_Body : Node_Id; 3360 Proc_Body_Id : Entity_Id; 3361 Proc_Decl : Node_Id; 3362 Proc_Id : Entity_Id; 3363 Stmts : List_Id := No_List; 3364 3365 CRec_Typ : Entity_Id := Empty; 3366 -- The corresponding record type of Full_Typ 3367 3368 Full_Proc : Entity_Id := Empty; 3369 -- The entity of the "full" invariant procedure 3370 3371 Full_Typ : Entity_Id := Empty; 3372 -- The full view of the working type 3373 3374 Obj_Id : Entity_Id := Empty; 3375 -- The _object formal parameter of the invariant procedure 3376 3377 Part_Proc : Entity_Id := Empty; 3378 -- The entity of the "partial" invariant procedure 3379 3380 Priv_Typ : Entity_Id := Empty; 3381 -- The partial view of the working type 3382 3383 Work_Typ : Entity_Id := Empty; 3384 -- The working type 3385 3386 -- Start of processing for Build_Invariant_Procedure_Body 3387 3388 begin 3389 Work_Typ := Typ; 3390 3391 -- Do not process the underlying full view of a private type. There is 3392 -- no way to get back to the partial view, plus the body will be built 3393 -- by the full view or the base type. 3394 3395 if Is_Underlying_Full_View (Work_Typ) then 3396 return; 3397 3398 -- The input type denotes the implementation base type of a constrained 3399 -- array type. Work with the first subtype as all invariant pragmas are 3400 -- on its rep item chain. 3401 3402 elsif Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then 3403 Work_Typ := First_Subtype (Work_Typ); 3404 3405 -- The input type denotes the corresponding record type of a protected 3406 -- or task type. Work with the concurrent type because the corresponding 3407 -- record type may not be visible to clients of the type. 3408 3409 elsif Ekind (Work_Typ) = E_Record_Type 3410 and then Is_Concurrent_Record_Type (Work_Typ) 3411 then 3412 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 3413 end if; 3414 3415 -- The working type may be subject to pragma Ghost. Set the mode now to 3416 -- ensure that the invariant procedure is properly marked as Ghost. 3417 3418 Set_Ghost_Mode (Work_Typ); 3419 3420 -- The type must either have invariants of its own, inherit class-wide 3421 -- invariants from parent types or interfaces, or be an array or record 3422 -- type whose components have invariants. 3423 3424 pragma Assert (Has_Invariants (Work_Typ)); 3425 3426 -- Interfaces are treated as the partial view of a private type in order 3427 -- to achieve uniformity with the general case. 3428 3429 if Is_Interface (Work_Typ) then 3430 Priv_Typ := Work_Typ; 3431 3432 -- Otherwise obtain both views of the type 3433 3434 else 3435 Get_Views (Work_Typ, Priv_Typ, Full_Typ, Dummy, CRec_Typ); 3436 end if; 3437 3438 -- The caller requests a body for the partial invariant procedure 3439 3440 if Partial_Invariant then 3441 Full_Proc := Invariant_Procedure (Work_Typ); 3442 Proc_Id := Partial_Invariant_Procedure (Work_Typ); 3443 3444 -- The "full" invariant procedure body was already created 3445 3446 if Present (Full_Proc) 3447 and then Present 3448 (Corresponding_Body (Unit_Declaration_Node (Full_Proc))) 3449 then 3450 -- This scenario happens only when the type is an untagged 3451 -- derivation from a private parent and the underlying full 3452 -- view was processed before the partial view. 3453 3454 pragma Assert 3455 (Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ)); 3456 3457 -- Nothing to do because the processing of the underlying full 3458 -- view already checked the invariants of the partial view. 3459 3460 goto Leave; 3461 end if; 3462 3463 -- Create a declaration for the "partial" invariant procedure if it 3464 -- is not available. 3465 3466 if No (Proc_Id) then 3467 Build_Invariant_Procedure_Declaration 3468 (Typ => Work_Typ, 3469 Partial_Invariant => True); 3470 3471 Proc_Id := Partial_Invariant_Procedure (Work_Typ); 3472 end if; 3473 3474 -- The caller requests a body for the "full" invariant procedure 3475 3476 else 3477 Proc_Id := Invariant_Procedure (Work_Typ); 3478 Part_Proc := Partial_Invariant_Procedure (Work_Typ); 3479 3480 -- Create a declaration for the "full" invariant procedure if it is 3481 -- not available. 3482 3483 if No (Proc_Id) then 3484 Build_Invariant_Procedure_Declaration (Work_Typ); 3485 Proc_Id := Invariant_Procedure (Work_Typ); 3486 end if; 3487 end if; 3488 3489 -- At this point there should be an invariant procedure declaration 3490 3491 pragma Assert (Present (Proc_Id)); 3492 Proc_Decl := Unit_Declaration_Node (Proc_Id); 3493 3494 -- Nothing to do if the invariant procedure already has a body 3495 3496 if Present (Corresponding_Body (Proc_Decl)) then 3497 goto Leave; 3498 end if; 3499 3500 -- Emulate the environment of the invariant procedure by installing its 3501 -- scope and formal parameters. Note that this is not needed, but having 3502 -- the scope installed helps with the detection of invariant-related 3503 -- errors. 3504 3505 Push_Scope (Proc_Id); 3506 Install_Formals (Proc_Id); 3507 3508 Obj_Id := First_Formal (Proc_Id); 3509 pragma Assert (Present (Obj_Id)); 3510 3511 -- The "partial" invariant procedure verifies the invariants of the 3512 -- partial view only. 3513 3514 if Partial_Invariant then 3515 pragma Assert (Present (Priv_Typ)); 3516 3517 Add_Own_Invariants 3518 (T => Priv_Typ, 3519 Obj_Id => Obj_Id, 3520 Checks => Stmts); 3521 3522 -- Otherwise the "full" invariant procedure verifies the invariants of 3523 -- the full view, all array or record components, as well as class-wide 3524 -- invariants inherited from parent types or interfaces. In addition, it 3525 -- indirectly verifies the invariants of the partial view by calling the 3526 -- "partial" invariant procedure. 3527 3528 else 3529 pragma Assert (Present (Full_Typ)); 3530 3531 -- Check the invariants of the partial view by calling the "partial" 3532 -- invariant procedure. Generate: 3533 3534 -- <Work_Typ>Partial_Invariant (_object); 3535 3536 if Present (Part_Proc) then 3537 Append_New_To (Stmts, 3538 Make_Procedure_Call_Statement (Loc, 3539 Name => New_Occurrence_Of (Part_Proc, Loc), 3540 Parameter_Associations => New_List ( 3541 New_Occurrence_Of (Obj_Id, Loc)))); 3542 3543 Produced_Check := True; 3544 end if; 3545 3546 Priv_Item := Empty; 3547 3548 -- Derived subtypes do not have a partial view 3549 3550 if Present (Priv_Typ) then 3551 3552 -- The processing of the "full" invariant procedure intentionally 3553 -- skips the partial view because a) this may result in changes of 3554 -- visibility and b) lead to duplicate checks. However, when the 3555 -- full view is the underlying full view of an untagged derived 3556 -- type whose parent type is private, partial invariants appear on 3557 -- the rep item chain of the partial view only. 3558 3559 -- package Pack_1 is 3560 -- type Root ... is private; 3561 -- private 3562 -- <full view of Root> 3563 -- end Pack_1; 3564 3565 -- with Pack_1; 3566 -- package Pack_2 is 3567 -- type Child is new Pack_1.Root with Type_Invariant => ...; 3568 -- <underlying full view of Child> 3569 -- end Pack_2; 3570 3571 -- As a result, the processing of the full view must also consider 3572 -- all invariants of the partial view. 3573 3574 if Is_Untagged_Private_Derivation (Priv_Typ, Full_Typ) then 3575 null; 3576 3577 -- Otherwise the invariants of the partial view are ignored 3578 3579 else 3580 -- Note that the rep item chain is shared between the partial 3581 -- and full views of a type. To avoid processing the invariants 3582 -- of the partial view, signal the logic to stop when the first 3583 -- rep item of the partial view has been reached. 3584 3585 Priv_Item := First_Rep_Item (Priv_Typ); 3586 3587 -- Ignore the invariants of the partial view by eliminating the 3588 -- view. 3589 3590 Priv_Typ := Empty; 3591 end if; 3592 end if; 3593 3594 -- Process the invariants of the full view and in certain cases those 3595 -- of the partial view. This also handles any invariants on array or 3596 -- record components. 3597 3598 Add_Own_Invariants 3599 (T => Priv_Typ, 3600 Obj_Id => Obj_Id, 3601 Checks => Stmts, 3602 Priv_Item => Priv_Item); 3603 3604 Add_Own_Invariants 3605 (T => Full_Typ, 3606 Obj_Id => Obj_Id, 3607 Checks => Stmts, 3608 Priv_Item => Priv_Item); 3609 3610 -- Process the elements of an array type 3611 3612 if Is_Array_Type (Full_Typ) then 3613 Add_Array_Component_Invariants (Full_Typ, Obj_Id, Stmts); 3614 3615 -- Process the components of a record type 3616 3617 elsif Ekind (Full_Typ) = E_Record_Type then 3618 Add_Record_Component_Invariants (Full_Typ, Obj_Id, Stmts); 3619 3620 -- Process the components of a corresponding record 3621 3622 elsif Present (CRec_Typ) then 3623 Add_Record_Component_Invariants (CRec_Typ, Obj_Id, Stmts); 3624 end if; 3625 3626 -- Process the inherited class-wide invariants of all parent types. 3627 -- This also handles any invariants on record components. 3628 3629 Add_Parent_Invariants (Full_Typ, Obj_Id, Stmts); 3630 3631 -- Process the inherited class-wide invariants of all implemented 3632 -- interface types. 3633 3634 Add_Interface_Invariants (Full_Typ, Obj_Id, Stmts); 3635 end if; 3636 3637 End_Scope; 3638 3639 -- At this point there should be at least one invariant check. If this 3640 -- is not the case, then the invariant-related flags were not properly 3641 -- set, or there is a missing invariant procedure on one of the array 3642 -- or record components. 3643 3644 pragma Assert (Produced_Check); 3645 3646 -- Account for the case where assertions are disabled or all invariant 3647 -- checks are subject to Assertion_Policy Ignore. Produce a completing 3648 -- empty body. 3649 3650 if No (Stmts) then 3651 Stmts := New_List (Make_Null_Statement (Loc)); 3652 end if; 3653 3654 -- Generate: 3655 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>) is 3656 -- begin 3657 -- <Stmts> 3658 -- end <Work_Typ>[Partial_]Invariant; 3659 3660 Proc_Body := 3661 Make_Subprogram_Body (Loc, 3662 Specification => 3663 Copy_Subprogram_Spec (Parent (Proc_Id)), 3664 Declarations => Empty_List, 3665 Handled_Statement_Sequence => 3666 Make_Handled_Sequence_Of_Statements (Loc, 3667 Statements => Stmts)); 3668 Proc_Body_Id := Defining_Entity (Proc_Body); 3669 3670 -- Perform minor decoration in case the body is not analyzed 3671 3672 Set_Ekind (Proc_Body_Id, E_Subprogram_Body); 3673 Set_Etype (Proc_Body_Id, Standard_Void_Type); 3674 Set_Scope (Proc_Body_Id, Current_Scope); 3675 3676 -- Link both spec and body to avoid generating duplicates 3677 3678 Set_Corresponding_Body (Proc_Decl, Proc_Body_Id); 3679 Set_Corresponding_Spec (Proc_Body, Proc_Id); 3680 3681 -- The body should not be inserted into the tree when the context is 3682 -- a generic unit because it is not part of the template. Note 3683 -- that the body must still be generated in order to resolve the 3684 -- invariants. 3685 3686 if Inside_A_Generic then 3687 null; 3688 3689 -- Semi-insert the body into the tree for GNATprove by setting its 3690 -- Parent field. This allows for proper upstream tree traversals. 3691 3692 elsif GNATprove_Mode then 3693 Set_Parent (Proc_Body, Parent (Declaration_Node (Work_Typ))); 3694 3695 -- Otherwise the body is part of the freezing actions of the type 3696 3697 else 3698 Append_Freeze_Action (Work_Typ, Proc_Body); 3699 end if; 3700 3701 <<Leave>> 3702 Restore_Ghost_Region (Saved_GM, Saved_IGR); 3703 end Build_Invariant_Procedure_Body; 3704 3705 ------------------------------------------- 3706 -- Build_Invariant_Procedure_Declaration -- 3707 ------------------------------------------- 3708 3709 -- WARNING: This routine manages Ghost regions. Return statements must be 3710 -- replaced by gotos which jump to the end of the routine and restore the 3711 -- Ghost mode. 3712 3713 procedure Build_Invariant_Procedure_Declaration 3714 (Typ : Entity_Id; 3715 Partial_Invariant : Boolean := False) 3716 is 3717 Loc : constant Source_Ptr := Sloc (Typ); 3718 3719 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 3720 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 3721 -- Save the Ghost-related attributes to restore on exit 3722 3723 Proc_Decl : Node_Id; 3724 Proc_Id : Entity_Id; 3725 Proc_Nam : Name_Id; 3726 Typ_Decl : Node_Id; 3727 3728 CRec_Typ : Entity_Id; 3729 -- The corresponding record type of Full_Typ 3730 3731 Full_Typ : Entity_Id; 3732 -- The full view of working type 3733 3734 Obj_Id : Entity_Id; 3735 -- The _object formal parameter of the invariant procedure 3736 3737 Obj_Typ : Entity_Id; 3738 -- The type of the _object formal parameter 3739 3740 Priv_Typ : Entity_Id; 3741 -- The partial view of working type 3742 3743 UFull_Typ : Entity_Id; 3744 -- The underlying full view of Full_Typ 3745 3746 Work_Typ : Entity_Id; 3747 -- The working type 3748 3749 begin 3750 Work_Typ := Typ; 3751 3752 -- The input type denotes the implementation base type of a constrained 3753 -- array type. Work with the first subtype as all invariant pragmas are 3754 -- on its rep item chain. 3755 3756 if Ekind (Work_Typ) = E_Array_Type and then Is_Itype (Work_Typ) then 3757 Work_Typ := First_Subtype (Work_Typ); 3758 3759 -- The input denotes the corresponding record type of a protected or a 3760 -- task type. Work with the concurrent type because the corresponding 3761 -- record type may not be visible to clients of the type. 3762 3763 elsif Ekind (Work_Typ) = E_Record_Type 3764 and then Is_Concurrent_Record_Type (Work_Typ) 3765 then 3766 Work_Typ := Corresponding_Concurrent_Type (Work_Typ); 3767 end if; 3768 3769 -- The working type may be subject to pragma Ghost. Set the mode now to 3770 -- ensure that the invariant procedure is properly marked as Ghost. 3771 3772 Set_Ghost_Mode (Work_Typ); 3773 3774 -- The type must either have invariants of its own, inherit class-wide 3775 -- invariants from parent or interface types, or be an array or record 3776 -- type whose components have invariants. 3777 3778 pragma Assert (Has_Invariants (Work_Typ)); 3779 3780 -- Nothing to do if the type already has a "partial" invariant procedure 3781 3782 if Partial_Invariant then 3783 if Present (Partial_Invariant_Procedure (Work_Typ)) then 3784 goto Leave; 3785 end if; 3786 3787 -- Nothing to do if the type already has a "full" invariant procedure 3788 3789 elsif Present (Invariant_Procedure (Work_Typ)) then 3790 goto Leave; 3791 end if; 3792 3793 -- The caller requests the declaration of the "partial" invariant 3794 -- procedure. 3795 3796 if Partial_Invariant then 3797 Proc_Nam := New_External_Name (Chars (Work_Typ), "Partial_Invariant"); 3798 3799 -- Otherwise the caller requests the declaration of the "full" invariant 3800 -- procedure. 3801 3802 else 3803 Proc_Nam := New_External_Name (Chars (Work_Typ), "Invariant"); 3804 end if; 3805 3806 Proc_Id := Make_Defining_Identifier (Loc, Chars => Proc_Nam); 3807 3808 -- Perform minor decoration in case the declaration is not analyzed 3809 3810 Set_Ekind (Proc_Id, E_Procedure); 3811 Set_Etype (Proc_Id, Standard_Void_Type); 3812 Set_Scope (Proc_Id, Current_Scope); 3813 3814 if Partial_Invariant then 3815 Set_Is_Partial_Invariant_Procedure (Proc_Id); 3816 Set_Partial_Invariant_Procedure (Work_Typ, Proc_Id); 3817 else 3818 Set_Is_Invariant_Procedure (Proc_Id); 3819 Set_Invariant_Procedure (Work_Typ, Proc_Id); 3820 end if; 3821 3822 -- The invariant procedure requires debug info when the invariants are 3823 -- subject to Source Coverage Obligations. 3824 3825 if Generate_SCO then 3826 Set_Debug_Info_Needed (Proc_Id); 3827 end if; 3828 3829 -- Obtain all views of the input type 3830 3831 Get_Views (Work_Typ, Priv_Typ, Full_Typ, UFull_Typ, CRec_Typ); 3832 3833 -- Associate the invariant procedure and various flags with all views 3834 3835 Propagate_Invariant_Attributes (Priv_Typ, From_Typ => Work_Typ); 3836 Propagate_Invariant_Attributes (Full_Typ, From_Typ => Work_Typ); 3837 Propagate_Invariant_Attributes (UFull_Typ, From_Typ => Work_Typ); 3838 Propagate_Invariant_Attributes (CRec_Typ, From_Typ => Work_Typ); 3839 3840 -- The declaration of the invariant procedure is inserted after the 3841 -- declaration of the partial view as this allows for proper external 3842 -- visibility. 3843 3844 if Present (Priv_Typ) then 3845 Typ_Decl := Declaration_Node (Priv_Typ); 3846 3847 -- Anonymous arrays in object declarations have no explicit declaration 3848 -- so use the related object declaration as the insertion point. 3849 3850 elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then 3851 Typ_Decl := Associated_Node_For_Itype (Work_Typ); 3852 3853 -- Derived types with the full view as parent do not have a partial 3854 -- view. Insert the invariant procedure after the derived type. 3855 3856 else 3857 Typ_Decl := Declaration_Node (Full_Typ); 3858 end if; 3859 3860 -- The type should have a declarative node 3861 3862 pragma Assert (Present (Typ_Decl)); 3863 3864 -- Create the formal parameter which emulates the variable-like behavior 3865 -- of the current type instance. 3866 3867 Obj_Id := Make_Defining_Identifier (Loc, Chars => Name_uObject); 3868 3869 -- When generating an invariant procedure declaration for an abstract 3870 -- type (including interfaces), use the class-wide type as the _object 3871 -- type. This has several desirable effects: 3872 3873 -- * The invariant procedure does not become a primitive of the type. 3874 -- This eliminates the need to either special case the treatment of 3875 -- invariant procedures, or to make it a predefined primitive and 3876 -- force every derived type to potentially provide an empty body. 3877 3878 -- * The invariant procedure does not need to be declared as abstract. 3879 -- This allows for a proper body, which in turn avoids redundant 3880 -- processing of the same invariants for types with multiple views. 3881 3882 -- * The class-wide type allows for calls to abstract primitives 3883 -- within a nonabstract subprogram. The calls are treated as 3884 -- dispatching and require additional processing when they are 3885 -- remapped to call primitives of derived types. See routine 3886 -- Replace_References for details. 3887 3888 if Is_Abstract_Type (Work_Typ) then 3889 Obj_Typ := Class_Wide_Type (Work_Typ); 3890 else 3891 Obj_Typ := Work_Typ; 3892 end if; 3893 3894 -- Perform minor decoration in case the declaration is not analyzed 3895 3896 Set_Ekind (Obj_Id, E_In_Parameter); 3897 Set_Etype (Obj_Id, Obj_Typ); 3898 Set_Scope (Obj_Id, Proc_Id); 3899 3900 Set_First_Entity (Proc_Id, Obj_Id); 3901 Set_Last_Entity (Proc_Id, Obj_Id); 3902 3903 -- Generate: 3904 -- procedure <Work_Typ>[Partial_]Invariant (_object : <Obj_Typ>); 3905 3906 Proc_Decl := 3907 Make_Subprogram_Declaration (Loc, 3908 Specification => 3909 Make_Procedure_Specification (Loc, 3910 Defining_Unit_Name => Proc_Id, 3911 Parameter_Specifications => New_List ( 3912 Make_Parameter_Specification (Loc, 3913 Defining_Identifier => Obj_Id, 3914 Parameter_Type => New_Occurrence_Of (Obj_Typ, Loc))))); 3915 3916 -- The declaration should not be inserted into the tree when the context 3917 -- is a generic unit because it is not part of the template. 3918 3919 if Inside_A_Generic then 3920 null; 3921 3922 -- Semi-insert the declaration into the tree for GNATprove by setting 3923 -- its Parent field. This allows for proper upstream tree traversals. 3924 3925 elsif GNATprove_Mode then 3926 Set_Parent (Proc_Decl, Parent (Typ_Decl)); 3927 3928 -- Otherwise insert the declaration 3929 3930 else 3931 pragma Assert (Present (Typ_Decl)); 3932 Insert_After_And_Analyze (Typ_Decl, Proc_Decl); 3933 end if; 3934 3935 <<Leave>> 3936 Restore_Ghost_Region (Saved_GM, Saved_IGR); 3937 end Build_Invariant_Procedure_Declaration; 3938 3939 -------------------------- 3940 -- Build_Procedure_Form -- 3941 -------------------------- 3942 3943 procedure Build_Procedure_Form (N : Node_Id) is 3944 Loc : constant Source_Ptr := Sloc (N); 3945 Subp : constant Entity_Id := Defining_Entity (N); 3946 3947 Func_Formal : Entity_Id; 3948 Proc_Formals : List_Id; 3949 Proc_Decl : Node_Id; 3950 3951 begin 3952 -- No action needed if this transformation was already done, or in case 3953 -- of subprogram renaming declarations. 3954 3955 if Nkind (Specification (N)) = N_Procedure_Specification 3956 or else Nkind (N) = N_Subprogram_Renaming_Declaration 3957 then 3958 return; 3959 end if; 3960 3961 -- Ditto when dealing with an expression function, where both the 3962 -- original expression and the generated declaration end up being 3963 -- expanded here. 3964 3965 if Rewritten_For_C (Subp) then 3966 return; 3967 end if; 3968 3969 Proc_Formals := New_List; 3970 3971 -- Create a list of formal parameters with the same types as the 3972 -- function. 3973 3974 Func_Formal := First_Formal (Subp); 3975 while Present (Func_Formal) loop 3976 Append_To (Proc_Formals, 3977 Make_Parameter_Specification (Loc, 3978 Defining_Identifier => 3979 Make_Defining_Identifier (Loc, Chars (Func_Formal)), 3980 Parameter_Type => 3981 New_Occurrence_Of (Etype (Func_Formal), Loc))); 3982 3983 Next_Formal (Func_Formal); 3984 end loop; 3985 3986 -- Add an extra out parameter to carry the function result 3987 3988 Append_To (Proc_Formals, 3989 Make_Parameter_Specification (Loc, 3990 Defining_Identifier => 3991 Make_Defining_Identifier (Loc, Name_UP_RESULT), 3992 Out_Present => True, 3993 Parameter_Type => New_Occurrence_Of (Etype (Subp), Loc))); 3994 3995 -- The new procedure declaration is inserted before the function 3996 -- declaration. The processing in Build_Procedure_Body_Form relies on 3997 -- this order. Note that we insert before because in the case of a 3998 -- function body with no separate spec, we do not want to insert the 3999 -- new spec after the body which will later get rewritten. 4000 4001 Proc_Decl := 4002 Make_Subprogram_Declaration (Loc, 4003 Specification => 4004 Make_Procedure_Specification (Loc, 4005 Defining_Unit_Name => 4006 Make_Defining_Identifier (Loc, Chars (Subp)), 4007 Parameter_Specifications => Proc_Formals)); 4008 4009 Insert_Before_And_Analyze (Unit_Declaration_Node (Subp), Proc_Decl); 4010 4011 -- Entity of procedure must remain invisible so that it does not 4012 -- overload subsequent references to the original function. 4013 4014 Set_Is_Immediately_Visible (Defining_Entity (Proc_Decl), False); 4015 4016 -- Mark the function as having a procedure form and link the function 4017 -- and its internally built procedure. 4018 4019 Set_Rewritten_For_C (Subp); 4020 Set_Corresponding_Procedure (Subp, Defining_Entity (Proc_Decl)); 4021 Set_Corresponding_Function (Defining_Entity (Proc_Decl), Subp); 4022 end Build_Procedure_Form; 4023 4024 ------------------------ 4025 -- Build_Runtime_Call -- 4026 ------------------------ 4027 4028 function Build_Runtime_Call (Loc : Source_Ptr; RE : RE_Id) return Node_Id is 4029 begin 4030 -- If entity is not available, we can skip making the call (this avoids 4031 -- junk duplicated error messages in a number of cases). 4032 4033 if not RTE_Available (RE) then 4034 return Make_Null_Statement (Loc); 4035 else 4036 return 4037 Make_Procedure_Call_Statement (Loc, 4038 Name => New_Occurrence_Of (RTE (RE), Loc)); 4039 end if; 4040 end Build_Runtime_Call; 4041 4042 ------------------------ 4043 -- Build_SS_Mark_Call -- 4044 ------------------------ 4045 4046 function Build_SS_Mark_Call 4047 (Loc : Source_Ptr; 4048 Mark : Entity_Id) return Node_Id 4049 is 4050 begin 4051 -- Generate: 4052 -- Mark : constant Mark_Id := SS_Mark; 4053 4054 return 4055 Make_Object_Declaration (Loc, 4056 Defining_Identifier => Mark, 4057 Constant_Present => True, 4058 Object_Definition => 4059 New_Occurrence_Of (RTE (RE_Mark_Id), Loc), 4060 Expression => 4061 Make_Function_Call (Loc, 4062 Name => New_Occurrence_Of (RTE (RE_SS_Mark), Loc))); 4063 end Build_SS_Mark_Call; 4064 4065 --------------------------- 4066 -- Build_SS_Release_Call -- 4067 --------------------------- 4068 4069 function Build_SS_Release_Call 4070 (Loc : Source_Ptr; 4071 Mark : Entity_Id) return Node_Id 4072 is 4073 begin 4074 -- Generate: 4075 -- SS_Release (Mark); 4076 4077 return 4078 Make_Procedure_Call_Statement (Loc, 4079 Name => 4080 New_Occurrence_Of (RTE (RE_SS_Release), Loc), 4081 Parameter_Associations => New_List ( 4082 New_Occurrence_Of (Mark, Loc))); 4083 end Build_SS_Release_Call; 4084 4085 ---------------------------- 4086 -- Build_Task_Array_Image -- 4087 ---------------------------- 4088 4089 -- This function generates the body for a function that constructs the 4090 -- image string for a task that is an array component. The function is 4091 -- local to the init proc for the array type, and is called for each one 4092 -- of the components. The constructed image has the form of an indexed 4093 -- component, whose prefix is the outer variable of the array type. 4094 -- The n-dimensional array type has known indexes Index, Index2... 4095 4096 -- Id_Ref is an indexed component form created by the enclosing init proc. 4097 -- Its successive indexes are Val1, Val2, ... which are the loop variables 4098 -- in the loops that call the individual task init proc on each component. 4099 4100 -- The generated function has the following structure: 4101 4102 -- function F return String is 4103 -- Pref : string renames Task_Name; 4104 -- T1 : String := Index1'Image (Val1); 4105 -- ... 4106 -- Tn : String := indexn'image (Valn); 4107 -- Len : Integer := T1'Length + ... + Tn'Length + n + 1; 4108 -- -- Len includes commas and the end parentheses. 4109 -- Res : String (1..Len); 4110 -- Pos : Integer := Pref'Length; 4111 -- 4112 -- begin 4113 -- Res (1 .. Pos) := Pref; 4114 -- Pos := Pos + 1; 4115 -- Res (Pos) := '('; 4116 -- Pos := Pos + 1; 4117 -- Res (Pos .. Pos + T1'Length - 1) := T1; 4118 -- Pos := Pos + T1'Length; 4119 -- Res (Pos) := '.'; 4120 -- Pos := Pos + 1; 4121 -- ... 4122 -- Res (Pos .. Pos + Tn'Length - 1) := Tn; 4123 -- Res (Len) := ')'; 4124 -- 4125 -- return Res; 4126 -- end F; 4127 -- 4128 -- Needless to say, multidimensional arrays of tasks are rare enough that 4129 -- the bulkiness of this code is not really a concern. 4130 4131 function Build_Task_Array_Image 4132 (Loc : Source_Ptr; 4133 Id_Ref : Node_Id; 4134 A_Type : Entity_Id; 4135 Dyn : Boolean := False) return Node_Id 4136 is 4137 Dims : constant Nat := Number_Dimensions (A_Type); 4138 -- Number of dimensions for array of tasks 4139 4140 Temps : array (1 .. Dims) of Entity_Id; 4141 -- Array of temporaries to hold string for each index 4142 4143 Indx : Node_Id; 4144 -- Index expression 4145 4146 Len : Entity_Id; 4147 -- Total length of generated name 4148 4149 Pos : Entity_Id; 4150 -- Running index for substring assignments 4151 4152 Pref : constant Entity_Id := Make_Temporary (Loc, 'P'); 4153 -- Name of enclosing variable, prefix of resulting name 4154 4155 Res : Entity_Id; 4156 -- String to hold result 4157 4158 Val : Node_Id; 4159 -- Value of successive indexes 4160 4161 Sum : Node_Id; 4162 -- Expression to compute total size of string 4163 4164 T : Entity_Id; 4165 -- Entity for name at one index position 4166 4167 Decls : constant List_Id := New_List; 4168 Stats : constant List_Id := New_List; 4169 4170 begin 4171 -- For a dynamic task, the name comes from the target variable. For a 4172 -- static one it is a formal of the enclosing init proc. 4173 4174 if Dyn then 4175 Get_Name_String (Chars (Entity (Prefix (Id_Ref)))); 4176 Append_To (Decls, 4177 Make_Object_Declaration (Loc, 4178 Defining_Identifier => Pref, 4179 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4180 Expression => 4181 Make_String_Literal (Loc, 4182 Strval => String_From_Name_Buffer))); 4183 4184 else 4185 Append_To (Decls, 4186 Make_Object_Renaming_Declaration (Loc, 4187 Defining_Identifier => Pref, 4188 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc), 4189 Name => Make_Identifier (Loc, Name_uTask_Name))); 4190 end if; 4191 4192 Indx := First_Index (A_Type); 4193 Val := First (Expressions (Id_Ref)); 4194 4195 for J in 1 .. Dims loop 4196 T := Make_Temporary (Loc, 'T'); 4197 Temps (J) := T; 4198 4199 Append_To (Decls, 4200 Make_Object_Declaration (Loc, 4201 Defining_Identifier => T, 4202 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4203 Expression => 4204 Make_Attribute_Reference (Loc, 4205 Attribute_Name => Name_Image, 4206 Prefix => New_Occurrence_Of (Etype (Indx), Loc), 4207 Expressions => New_List (New_Copy_Tree (Val))))); 4208 4209 Next_Index (Indx); 4210 Next (Val); 4211 end loop; 4212 4213 Sum := Make_Integer_Literal (Loc, Dims + 1); 4214 4215 Sum := 4216 Make_Op_Add (Loc, 4217 Left_Opnd => Sum, 4218 Right_Opnd => 4219 Make_Attribute_Reference (Loc, 4220 Attribute_Name => Name_Length, 4221 Prefix => New_Occurrence_Of (Pref, Loc), 4222 Expressions => New_List (Make_Integer_Literal (Loc, 1)))); 4223 4224 for J in 1 .. Dims loop 4225 Sum := 4226 Make_Op_Add (Loc, 4227 Left_Opnd => Sum, 4228 Right_Opnd => 4229 Make_Attribute_Reference (Loc, 4230 Attribute_Name => Name_Length, 4231 Prefix => 4232 New_Occurrence_Of (Temps (J), Loc), 4233 Expressions => New_List (Make_Integer_Literal (Loc, 1)))); 4234 end loop; 4235 4236 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats); 4237 4238 Set_Character_Literal_Name (Char_Code (Character'Pos ('('))); 4239 4240 Append_To (Stats, 4241 Make_Assignment_Statement (Loc, 4242 Name => 4243 Make_Indexed_Component (Loc, 4244 Prefix => New_Occurrence_Of (Res, Loc), 4245 Expressions => New_List (New_Occurrence_Of (Pos, Loc))), 4246 Expression => 4247 Make_Character_Literal (Loc, 4248 Chars => Name_Find, 4249 Char_Literal_Value => UI_From_Int (Character'Pos ('('))))); 4250 4251 Append_To (Stats, 4252 Make_Assignment_Statement (Loc, 4253 Name => New_Occurrence_Of (Pos, Loc), 4254 Expression => 4255 Make_Op_Add (Loc, 4256 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4257 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 4258 4259 for J in 1 .. Dims loop 4260 4261 Append_To (Stats, 4262 Make_Assignment_Statement (Loc, 4263 Name => 4264 Make_Slice (Loc, 4265 Prefix => New_Occurrence_Of (Res, Loc), 4266 Discrete_Range => 4267 Make_Range (Loc, 4268 Low_Bound => New_Occurrence_Of (Pos, Loc), 4269 High_Bound => 4270 Make_Op_Subtract (Loc, 4271 Left_Opnd => 4272 Make_Op_Add (Loc, 4273 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4274 Right_Opnd => 4275 Make_Attribute_Reference (Loc, 4276 Attribute_Name => Name_Length, 4277 Prefix => 4278 New_Occurrence_Of (Temps (J), Loc), 4279 Expressions => 4280 New_List (Make_Integer_Literal (Loc, 1)))), 4281 Right_Opnd => Make_Integer_Literal (Loc, 1)))), 4282 4283 Expression => New_Occurrence_Of (Temps (J), Loc))); 4284 4285 if J < Dims then 4286 Append_To (Stats, 4287 Make_Assignment_Statement (Loc, 4288 Name => New_Occurrence_Of (Pos, Loc), 4289 Expression => 4290 Make_Op_Add (Loc, 4291 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4292 Right_Opnd => 4293 Make_Attribute_Reference (Loc, 4294 Attribute_Name => Name_Length, 4295 Prefix => New_Occurrence_Of (Temps (J), Loc), 4296 Expressions => 4297 New_List (Make_Integer_Literal (Loc, 1)))))); 4298 4299 Set_Character_Literal_Name (Char_Code (Character'Pos (','))); 4300 4301 Append_To (Stats, 4302 Make_Assignment_Statement (Loc, 4303 Name => Make_Indexed_Component (Loc, 4304 Prefix => New_Occurrence_Of (Res, Loc), 4305 Expressions => New_List (New_Occurrence_Of (Pos, Loc))), 4306 Expression => 4307 Make_Character_Literal (Loc, 4308 Chars => Name_Find, 4309 Char_Literal_Value => UI_From_Int (Character'Pos (','))))); 4310 4311 Append_To (Stats, 4312 Make_Assignment_Statement (Loc, 4313 Name => New_Occurrence_Of (Pos, Loc), 4314 Expression => 4315 Make_Op_Add (Loc, 4316 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4317 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 4318 end if; 4319 end loop; 4320 4321 Set_Character_Literal_Name (Char_Code (Character'Pos (')'))); 4322 4323 Append_To (Stats, 4324 Make_Assignment_Statement (Loc, 4325 Name => 4326 Make_Indexed_Component (Loc, 4327 Prefix => New_Occurrence_Of (Res, Loc), 4328 Expressions => New_List (New_Occurrence_Of (Len, Loc))), 4329 Expression => 4330 Make_Character_Literal (Loc, 4331 Chars => Name_Find, 4332 Char_Literal_Value => UI_From_Int (Character'Pos (')'))))); 4333 return Build_Task_Image_Function (Loc, Decls, Stats, Res); 4334 end Build_Task_Array_Image; 4335 4336 ---------------------------- 4337 -- Build_Task_Image_Decls -- 4338 ---------------------------- 4339 4340 function Build_Task_Image_Decls 4341 (Loc : Source_Ptr; 4342 Id_Ref : Node_Id; 4343 A_Type : Entity_Id; 4344 In_Init_Proc : Boolean := False) return List_Id 4345 is 4346 Decls : constant List_Id := New_List; 4347 T_Id : Entity_Id := Empty; 4348 Decl : Node_Id; 4349 Expr : Node_Id := Empty; 4350 Fun : Node_Id := Empty; 4351 Is_Dyn : constant Boolean := 4352 Nkind (Parent (Id_Ref)) = N_Assignment_Statement 4353 and then 4354 Nkind (Expression (Parent (Id_Ref))) = N_Allocator; 4355 4356 begin 4357 -- If Discard_Names or No_Implicit_Heap_Allocations are in effect, 4358 -- generate a dummy declaration only. 4359 4360 if Restriction_Active (No_Implicit_Heap_Allocations) 4361 or else Global_Discard_Names 4362 then 4363 T_Id := Make_Temporary (Loc, 'J'); 4364 Name_Len := 0; 4365 4366 return 4367 New_List ( 4368 Make_Object_Declaration (Loc, 4369 Defining_Identifier => T_Id, 4370 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4371 Expression => 4372 Make_String_Literal (Loc, 4373 Strval => String_From_Name_Buffer))); 4374 4375 else 4376 if Nkind (Id_Ref) = N_Identifier 4377 or else Nkind (Id_Ref) = N_Defining_Identifier 4378 then 4379 -- For a simple variable, the image of the task is built from 4380 -- the name of the variable. To avoid possible conflict with the 4381 -- anonymous type created for a single protected object, add a 4382 -- numeric suffix. 4383 4384 T_Id := 4385 Make_Defining_Identifier (Loc, 4386 New_External_Name (Chars (Id_Ref), 'T', 1)); 4387 4388 Get_Name_String (Chars (Id_Ref)); 4389 4390 Expr := 4391 Make_String_Literal (Loc, 4392 Strval => String_From_Name_Buffer); 4393 4394 elsif Nkind (Id_Ref) = N_Selected_Component then 4395 T_Id := 4396 Make_Defining_Identifier (Loc, 4397 New_External_Name (Chars (Selector_Name (Id_Ref)), 'T')); 4398 Fun := Build_Task_Record_Image (Loc, Id_Ref, Is_Dyn); 4399 4400 elsif Nkind (Id_Ref) = N_Indexed_Component then 4401 T_Id := 4402 Make_Defining_Identifier (Loc, 4403 New_External_Name (Chars (A_Type), 'N')); 4404 4405 Fun := Build_Task_Array_Image (Loc, Id_Ref, A_Type, Is_Dyn); 4406 end if; 4407 end if; 4408 4409 if Present (Fun) then 4410 Append (Fun, Decls); 4411 Expr := Make_Function_Call (Loc, 4412 Name => New_Occurrence_Of (Defining_Entity (Fun), Loc)); 4413 4414 if not In_Init_Proc then 4415 Set_Uses_Sec_Stack (Defining_Entity (Fun)); 4416 end if; 4417 end if; 4418 4419 Decl := Make_Object_Declaration (Loc, 4420 Defining_Identifier => T_Id, 4421 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4422 Constant_Present => True, 4423 Expression => Expr); 4424 4425 Append (Decl, Decls); 4426 return Decls; 4427 end Build_Task_Image_Decls; 4428 4429 ------------------------------- 4430 -- Build_Task_Image_Function -- 4431 ------------------------------- 4432 4433 function Build_Task_Image_Function 4434 (Loc : Source_Ptr; 4435 Decls : List_Id; 4436 Stats : List_Id; 4437 Res : Entity_Id) return Node_Id 4438 is 4439 Spec : Node_Id; 4440 4441 begin 4442 Append_To (Stats, 4443 Make_Simple_Return_Statement (Loc, 4444 Expression => New_Occurrence_Of (Res, Loc))); 4445 4446 Spec := Make_Function_Specification (Loc, 4447 Defining_Unit_Name => Make_Temporary (Loc, 'F'), 4448 Result_Definition => New_Occurrence_Of (Standard_String, Loc)); 4449 4450 -- Calls to 'Image use the secondary stack, which must be cleaned up 4451 -- after the task name is built. 4452 4453 return Make_Subprogram_Body (Loc, 4454 Specification => Spec, 4455 Declarations => Decls, 4456 Handled_Statement_Sequence => 4457 Make_Handled_Sequence_Of_Statements (Loc, Statements => Stats)); 4458 end Build_Task_Image_Function; 4459 4460 ----------------------------- 4461 -- Build_Task_Image_Prefix -- 4462 ----------------------------- 4463 4464 procedure Build_Task_Image_Prefix 4465 (Loc : Source_Ptr; 4466 Len : out Entity_Id; 4467 Res : out Entity_Id; 4468 Pos : out Entity_Id; 4469 Prefix : Entity_Id; 4470 Sum : Node_Id; 4471 Decls : List_Id; 4472 Stats : List_Id) 4473 is 4474 begin 4475 Len := Make_Temporary (Loc, 'L', Sum); 4476 4477 Append_To (Decls, 4478 Make_Object_Declaration (Loc, 4479 Defining_Identifier => Len, 4480 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc), 4481 Expression => Sum)); 4482 4483 Res := Make_Temporary (Loc, 'R'); 4484 4485 Append_To (Decls, 4486 Make_Object_Declaration (Loc, 4487 Defining_Identifier => Res, 4488 Object_Definition => 4489 Make_Subtype_Indication (Loc, 4490 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc), 4491 Constraint => 4492 Make_Index_Or_Discriminant_Constraint (Loc, 4493 Constraints => 4494 New_List ( 4495 Make_Range (Loc, 4496 Low_Bound => Make_Integer_Literal (Loc, 1), 4497 High_Bound => New_Occurrence_Of (Len, Loc))))))); 4498 4499 -- Indicate that the result is an internal temporary, so it does not 4500 -- receive a bogus initialization when declaration is expanded. This 4501 -- is both efficient, and prevents anomalies in the handling of 4502 -- dynamic objects on the secondary stack. 4503 4504 Set_Is_Internal (Res); 4505 Pos := Make_Temporary (Loc, 'P'); 4506 4507 Append_To (Decls, 4508 Make_Object_Declaration (Loc, 4509 Defining_Identifier => Pos, 4510 Object_Definition => New_Occurrence_Of (Standard_Integer, Loc))); 4511 4512 -- Pos := Prefix'Length; 4513 4514 Append_To (Stats, 4515 Make_Assignment_Statement (Loc, 4516 Name => New_Occurrence_Of (Pos, Loc), 4517 Expression => 4518 Make_Attribute_Reference (Loc, 4519 Attribute_Name => Name_Length, 4520 Prefix => New_Occurrence_Of (Prefix, Loc), 4521 Expressions => New_List (Make_Integer_Literal (Loc, 1))))); 4522 4523 -- Res (1 .. Pos) := Prefix; 4524 4525 Append_To (Stats, 4526 Make_Assignment_Statement (Loc, 4527 Name => 4528 Make_Slice (Loc, 4529 Prefix => New_Occurrence_Of (Res, Loc), 4530 Discrete_Range => 4531 Make_Range (Loc, 4532 Low_Bound => Make_Integer_Literal (Loc, 1), 4533 High_Bound => New_Occurrence_Of (Pos, Loc))), 4534 4535 Expression => New_Occurrence_Of (Prefix, Loc))); 4536 4537 Append_To (Stats, 4538 Make_Assignment_Statement (Loc, 4539 Name => New_Occurrence_Of (Pos, Loc), 4540 Expression => 4541 Make_Op_Add (Loc, 4542 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4543 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 4544 end Build_Task_Image_Prefix; 4545 4546 ----------------------------- 4547 -- Build_Task_Record_Image -- 4548 ----------------------------- 4549 4550 function Build_Task_Record_Image 4551 (Loc : Source_Ptr; 4552 Id_Ref : Node_Id; 4553 Dyn : Boolean := False) return Node_Id 4554 is 4555 Len : Entity_Id; 4556 -- Total length of generated name 4557 4558 Pos : Entity_Id; 4559 -- Index into result 4560 4561 Res : Entity_Id; 4562 -- String to hold result 4563 4564 Pref : constant Entity_Id := Make_Temporary (Loc, 'P'); 4565 -- Name of enclosing variable, prefix of resulting name 4566 4567 Sum : Node_Id; 4568 -- Expression to compute total size of string 4569 4570 Sel : Entity_Id; 4571 -- Entity for selector name 4572 4573 Decls : constant List_Id := New_List; 4574 Stats : constant List_Id := New_List; 4575 4576 begin 4577 -- For a dynamic task, the name comes from the target variable. For a 4578 -- static one it is a formal of the enclosing init proc. 4579 4580 if Dyn then 4581 Get_Name_String (Chars (Entity (Prefix (Id_Ref)))); 4582 Append_To (Decls, 4583 Make_Object_Declaration (Loc, 4584 Defining_Identifier => Pref, 4585 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4586 Expression => 4587 Make_String_Literal (Loc, 4588 Strval => String_From_Name_Buffer))); 4589 4590 else 4591 Append_To (Decls, 4592 Make_Object_Renaming_Declaration (Loc, 4593 Defining_Identifier => Pref, 4594 Subtype_Mark => New_Occurrence_Of (Standard_String, Loc), 4595 Name => Make_Identifier (Loc, Name_uTask_Name))); 4596 end if; 4597 4598 Sel := Make_Temporary (Loc, 'S'); 4599 4600 Get_Name_String (Chars (Selector_Name (Id_Ref))); 4601 4602 Append_To (Decls, 4603 Make_Object_Declaration (Loc, 4604 Defining_Identifier => Sel, 4605 Object_Definition => New_Occurrence_Of (Standard_String, Loc), 4606 Expression => 4607 Make_String_Literal (Loc, 4608 Strval => String_From_Name_Buffer))); 4609 4610 Sum := Make_Integer_Literal (Loc, Nat (Name_Len + 1)); 4611 4612 Sum := 4613 Make_Op_Add (Loc, 4614 Left_Opnd => Sum, 4615 Right_Opnd => 4616 Make_Attribute_Reference (Loc, 4617 Attribute_Name => Name_Length, 4618 Prefix => 4619 New_Occurrence_Of (Pref, Loc), 4620 Expressions => New_List (Make_Integer_Literal (Loc, 1)))); 4621 4622 Build_Task_Image_Prefix (Loc, Len, Res, Pos, Pref, Sum, Decls, Stats); 4623 4624 Set_Character_Literal_Name (Char_Code (Character'Pos ('.'))); 4625 4626 -- Res (Pos) := '.'; 4627 4628 Append_To (Stats, 4629 Make_Assignment_Statement (Loc, 4630 Name => Make_Indexed_Component (Loc, 4631 Prefix => New_Occurrence_Of (Res, Loc), 4632 Expressions => New_List (New_Occurrence_Of (Pos, Loc))), 4633 Expression => 4634 Make_Character_Literal (Loc, 4635 Chars => Name_Find, 4636 Char_Literal_Value => 4637 UI_From_Int (Character'Pos ('.'))))); 4638 4639 Append_To (Stats, 4640 Make_Assignment_Statement (Loc, 4641 Name => New_Occurrence_Of (Pos, Loc), 4642 Expression => 4643 Make_Op_Add (Loc, 4644 Left_Opnd => New_Occurrence_Of (Pos, Loc), 4645 Right_Opnd => Make_Integer_Literal (Loc, 1)))); 4646 4647 -- Res (Pos .. Len) := Selector; 4648 4649 Append_To (Stats, 4650 Make_Assignment_Statement (Loc, 4651 Name => Make_Slice (Loc, 4652 Prefix => New_Occurrence_Of (Res, Loc), 4653 Discrete_Range => 4654 Make_Range (Loc, 4655 Low_Bound => New_Occurrence_Of (Pos, Loc), 4656 High_Bound => New_Occurrence_Of (Len, Loc))), 4657 Expression => New_Occurrence_Of (Sel, Loc))); 4658 4659 return Build_Task_Image_Function (Loc, Decls, Stats, Res); 4660 end Build_Task_Record_Image; 4661 4662 --------------------------------------- 4663 -- Build_Transient_Object_Statements -- 4664 --------------------------------------- 4665 4666 procedure Build_Transient_Object_Statements 4667 (Obj_Decl : Node_Id; 4668 Fin_Call : out Node_Id; 4669 Hook_Assign : out Node_Id; 4670 Hook_Clear : out Node_Id; 4671 Hook_Decl : out Node_Id; 4672 Ptr_Decl : out Node_Id; 4673 Finalize_Obj : Boolean := True) 4674 is 4675 Loc : constant Source_Ptr := Sloc (Obj_Decl); 4676 Obj_Id : constant Entity_Id := Defining_Entity (Obj_Decl); 4677 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); 4678 4679 Desig_Typ : Entity_Id; 4680 Hook_Expr : Node_Id; 4681 Hook_Id : Entity_Id; 4682 Obj_Ref : Node_Id; 4683 Ptr_Typ : Entity_Id; 4684 4685 begin 4686 -- Recover the type of the object 4687 4688 Desig_Typ := Obj_Typ; 4689 4690 if Is_Access_Type (Desig_Typ) then 4691 Desig_Typ := Available_View (Designated_Type (Desig_Typ)); 4692 end if; 4693 4694 -- Create an access type which provides a reference to the transient 4695 -- object. Generate: 4696 4697 -- type Ptr_Typ is access all Desig_Typ; 4698 4699 Ptr_Typ := Make_Temporary (Loc, 'A'); 4700 Set_Ekind (Ptr_Typ, E_General_Access_Type); 4701 Set_Directly_Designated_Type (Ptr_Typ, Desig_Typ); 4702 4703 Ptr_Decl := 4704 Make_Full_Type_Declaration (Loc, 4705 Defining_Identifier => Ptr_Typ, 4706 Type_Definition => 4707 Make_Access_To_Object_Definition (Loc, 4708 All_Present => True, 4709 Subtype_Indication => New_Occurrence_Of (Desig_Typ, Loc))); 4710 4711 -- Create a temporary check which acts as a hook to the transient 4712 -- object. Generate: 4713 4714 -- Hook : Ptr_Typ := null; 4715 4716 Hook_Id := Make_Temporary (Loc, 'T'); 4717 Set_Ekind (Hook_Id, E_Variable); 4718 Set_Etype (Hook_Id, Ptr_Typ); 4719 4720 Hook_Decl := 4721 Make_Object_Declaration (Loc, 4722 Defining_Identifier => Hook_Id, 4723 Object_Definition => New_Occurrence_Of (Ptr_Typ, Loc), 4724 Expression => Make_Null (Loc)); 4725 4726 -- Mark the temporary as a hook. This signals the machinery in 4727 -- Build_Finalizer to recognize this special case. 4728 4729 Set_Status_Flag_Or_Transient_Decl (Hook_Id, Obj_Decl); 4730 4731 -- Hook the transient object to the temporary. Generate: 4732 4733 -- Hook := Ptr_Typ (Obj_Id); 4734 -- <or> 4735 -- Hool := Obj_Id'Unrestricted_Access; 4736 4737 if Is_Access_Type (Obj_Typ) then 4738 Hook_Expr := 4739 Unchecked_Convert_To (Ptr_Typ, New_Occurrence_Of (Obj_Id, Loc)); 4740 else 4741 Hook_Expr := 4742 Make_Attribute_Reference (Loc, 4743 Prefix => New_Occurrence_Of (Obj_Id, Loc), 4744 Attribute_Name => Name_Unrestricted_Access); 4745 end if; 4746 4747 Hook_Assign := 4748 Make_Assignment_Statement (Loc, 4749 Name => New_Occurrence_Of (Hook_Id, Loc), 4750 Expression => Hook_Expr); 4751 4752 -- Crear the hook prior to finalizing the object. Generate: 4753 4754 -- Hook := null; 4755 4756 Hook_Clear := 4757 Make_Assignment_Statement (Loc, 4758 Name => New_Occurrence_Of (Hook_Id, Loc), 4759 Expression => Make_Null (Loc)); 4760 4761 -- Finalize the object. Generate: 4762 4763 -- [Deep_]Finalize (Obj_Ref[.all]); 4764 4765 if Finalize_Obj then 4766 Obj_Ref := New_Occurrence_Of (Obj_Id, Loc); 4767 4768 if Is_Access_Type (Obj_Typ) then 4769 Obj_Ref := Make_Explicit_Dereference (Loc, Obj_Ref); 4770 Set_Etype (Obj_Ref, Desig_Typ); 4771 end if; 4772 4773 Fin_Call := 4774 Make_Final_Call 4775 (Obj_Ref => Obj_Ref, 4776 Typ => Desig_Typ); 4777 4778 -- Otherwise finalize the hook. Generate: 4779 4780 -- [Deep_]Finalize (Hook.all); 4781 4782 else 4783 Fin_Call := 4784 Make_Final_Call ( 4785 Obj_Ref => 4786 Make_Explicit_Dereference (Loc, 4787 Prefix => New_Occurrence_Of (Hook_Id, Loc)), 4788 Typ => Desig_Typ); 4789 end if; 4790 end Build_Transient_Object_Statements; 4791 4792 ----------------------------- 4793 -- Check_Float_Op_Overflow -- 4794 ----------------------------- 4795 4796 procedure Check_Float_Op_Overflow (N : Node_Id) is 4797 begin 4798 -- Return if no check needed 4799 4800 if not Is_Floating_Point_Type (Etype (N)) 4801 or else not (Do_Overflow_Check (N) and then Check_Float_Overflow) 4802 4803 -- In CodePeer_Mode, rely on the overflow check flag being set instead 4804 -- and do not expand the code for float overflow checking. 4805 4806 or else CodePeer_Mode 4807 then 4808 return; 4809 end if; 4810 4811 -- Otherwise we replace the expression by 4812 4813 -- do Tnn : constant ftype := expression; 4814 -- constraint_error when not Tnn'Valid; 4815 -- in Tnn; 4816 4817 declare 4818 Loc : constant Source_Ptr := Sloc (N); 4819 Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N); 4820 Typ : constant Entity_Id := Etype (N); 4821 4822 begin 4823 -- Turn off the Do_Overflow_Check flag, since we are doing that work 4824 -- right here. We also set the node as analyzed to prevent infinite 4825 -- recursion from repeating the operation in the expansion. 4826 4827 Set_Do_Overflow_Check (N, False); 4828 Set_Analyzed (N, True); 4829 4830 -- Do the rewrite to include the check 4831 4832 Rewrite (N, 4833 Make_Expression_With_Actions (Loc, 4834 Actions => New_List ( 4835 Make_Object_Declaration (Loc, 4836 Defining_Identifier => Tnn, 4837 Object_Definition => New_Occurrence_Of (Typ, Loc), 4838 Constant_Present => True, 4839 Expression => Relocate_Node (N)), 4840 Make_Raise_Constraint_Error (Loc, 4841 Condition => 4842 Make_Op_Not (Loc, 4843 Right_Opnd => 4844 Make_Attribute_Reference (Loc, 4845 Prefix => New_Occurrence_Of (Tnn, Loc), 4846 Attribute_Name => Name_Valid)), 4847 Reason => CE_Overflow_Check_Failed)), 4848 Expression => New_Occurrence_Of (Tnn, Loc))); 4849 4850 Analyze_And_Resolve (N, Typ); 4851 end; 4852 end Check_Float_Op_Overflow; 4853 4854 ---------------------------------- 4855 -- Component_May_Be_Bit_Aligned -- 4856 ---------------------------------- 4857 4858 function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is 4859 UT : Entity_Id; 4860 4861 begin 4862 -- If no component clause, then everything is fine, since the back end 4863 -- never misaligns from byte boundaries by default, even if there is a 4864 -- pragma Pack for the record. 4865 4866 if No (Comp) or else No (Component_Clause (Comp)) then 4867 return False; 4868 end if; 4869 4870 UT := Underlying_Type (Etype (Comp)); 4871 4872 -- It is only array and record types that cause trouble 4873 4874 if not Is_Record_Type (UT) and then not Is_Array_Type (UT) then 4875 return False; 4876 4877 -- If we know that we have a small (at most the maximum integer size) 4878 -- record or bit-packed array, then everything is fine, since the back 4879 -- end can handle these cases correctly. 4880 4881 elsif Esize (Comp) <= System_Max_Integer_Size 4882 and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT)) 4883 then 4884 return False; 4885 4886 -- Otherwise if the component is not byte aligned, we know we have the 4887 -- nasty unaligned case. 4888 4889 elsif Normalized_First_Bit (Comp) /= Uint_0 4890 or else Esize (Comp) mod System_Storage_Unit /= Uint_0 4891 then 4892 return True; 4893 4894 -- If we are large and byte aligned, then OK at this level 4895 4896 else 4897 return False; 4898 end if; 4899 end Component_May_Be_Bit_Aligned; 4900 4901 ------------------------------- 4902 -- Convert_To_Actual_Subtype -- 4903 ------------------------------- 4904 4905 procedure Convert_To_Actual_Subtype (Exp : Entity_Id) is 4906 Act_ST : Entity_Id; 4907 4908 begin 4909 Act_ST := Get_Actual_Subtype (Exp); 4910 4911 if Act_ST = Etype (Exp) then 4912 return; 4913 else 4914 Rewrite (Exp, Convert_To (Act_ST, Relocate_Node (Exp))); 4915 Analyze_And_Resolve (Exp, Act_ST); 4916 end if; 4917 end Convert_To_Actual_Subtype; 4918 4919 ----------------------------------- 4920 -- Corresponding_Runtime_Package -- 4921 ----------------------------------- 4922 4923 function Corresponding_Runtime_Package (Typ : Entity_Id) return RTU_Id is 4924 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean; 4925 -- Return True if protected type T has one entry and the maximum queue 4926 -- length is one. 4927 4928 -------------------------------- 4929 -- Has_One_Entry_And_No_Queue -- 4930 -------------------------------- 4931 4932 function Has_One_Entry_And_No_Queue (T : Entity_Id) return Boolean is 4933 Item : Entity_Id; 4934 Is_First : Boolean := True; 4935 4936 begin 4937 Item := First_Entity (T); 4938 while Present (Item) loop 4939 if Is_Entry (Item) then 4940 4941 -- The protected type has more than one entry 4942 4943 if not Is_First then 4944 return False; 4945 end if; 4946 4947 -- The queue length is not one 4948 4949 if not Restriction_Active (No_Entry_Queue) 4950 and then Get_Max_Queue_Length (Item) /= Uint_1 4951 then 4952 return False; 4953 end if; 4954 4955 Is_First := False; 4956 end if; 4957 4958 Next_Entity (Item); 4959 end loop; 4960 4961 return True; 4962 end Has_One_Entry_And_No_Queue; 4963 4964 -- Local variables 4965 4966 Pkg_Id : RTU_Id := RTU_Null; 4967 4968 -- Start of processing for Corresponding_Runtime_Package 4969 4970 begin 4971 pragma Assert (Is_Concurrent_Type (Typ)); 4972 4973 if Is_Protected_Type (Typ) then 4974 if Has_Entries (Typ) 4975 4976 -- A protected type without entries that covers an interface and 4977 -- overrides the abstract routines with protected procedures is 4978 -- considered equivalent to a protected type with entries in the 4979 -- context of dispatching select statements. It is sufficient to 4980 -- check for the presence of an interface list in the declaration 4981 -- node to recognize this case. 4982 4983 or else Present (Interface_List (Parent (Typ))) 4984 4985 -- Protected types with interrupt handlers (when not using a 4986 -- restricted profile) are also considered equivalent to 4987 -- protected types with entries. The types which are used 4988 -- (Static_Interrupt_Protection and Dynamic_Interrupt_Protection) 4989 -- are derived from Protection_Entries. 4990 4991 or else (Has_Attach_Handler (Typ) and then not Restricted_Profile) 4992 or else Has_Interrupt_Handler (Typ) 4993 then 4994 if Abort_Allowed 4995 or else Restriction_Active (No_Select_Statements) = False 4996 or else not Has_One_Entry_And_No_Queue (Typ) 4997 or else (Has_Attach_Handler (Typ) 4998 and then not Restricted_Profile) 4999 then 5000 Pkg_Id := System_Tasking_Protected_Objects_Entries; 5001 else 5002 Pkg_Id := System_Tasking_Protected_Objects_Single_Entry; 5003 end if; 5004 5005 else 5006 Pkg_Id := System_Tasking_Protected_Objects; 5007 end if; 5008 end if; 5009 5010 return Pkg_Id; 5011 end Corresponding_Runtime_Package; 5012 5013 ----------------------------------- 5014 -- Current_Sem_Unit_Declarations -- 5015 ----------------------------------- 5016 5017 function Current_Sem_Unit_Declarations return List_Id is 5018 U : Node_Id := Unit (Cunit (Current_Sem_Unit)); 5019 Decls : List_Id; 5020 5021 begin 5022 -- If the current unit is a package body, locate the visible 5023 -- declarations of the package spec. 5024 5025 if Nkind (U) = N_Package_Body then 5026 U := Unit (Library_Unit (Cunit (Current_Sem_Unit))); 5027 end if; 5028 5029 if Nkind (U) = N_Package_Declaration then 5030 U := Specification (U); 5031 Decls := Visible_Declarations (U); 5032 5033 if No (Decls) then 5034 Decls := New_List; 5035 Set_Visible_Declarations (U, Decls); 5036 end if; 5037 5038 else 5039 Decls := Declarations (U); 5040 5041 if No (Decls) then 5042 Decls := New_List; 5043 Set_Declarations (U, Decls); 5044 end if; 5045 end if; 5046 5047 return Decls; 5048 end Current_Sem_Unit_Declarations; 5049 5050 ----------------------- 5051 -- Duplicate_Subexpr -- 5052 ----------------------- 5053 5054 function Duplicate_Subexpr 5055 (Exp : Node_Id; 5056 Name_Req : Boolean := False; 5057 Renaming_Req : Boolean := False) return Node_Id 5058 is 5059 begin 5060 Remove_Side_Effects (Exp, Name_Req, Renaming_Req); 5061 return New_Copy_Tree (Exp); 5062 end Duplicate_Subexpr; 5063 5064 --------------------------------- 5065 -- Duplicate_Subexpr_No_Checks -- 5066 --------------------------------- 5067 5068 function Duplicate_Subexpr_No_Checks 5069 (Exp : Node_Id; 5070 Name_Req : Boolean := False; 5071 Renaming_Req : Boolean := False; 5072 Related_Id : Entity_Id := Empty; 5073 Is_Low_Bound : Boolean := False; 5074 Is_High_Bound : Boolean := False) return Node_Id 5075 is 5076 New_Exp : Node_Id; 5077 5078 begin 5079 Remove_Side_Effects 5080 (Exp => Exp, 5081 Name_Req => Name_Req, 5082 Renaming_Req => Renaming_Req, 5083 Related_Id => Related_Id, 5084 Is_Low_Bound => Is_Low_Bound, 5085 Is_High_Bound => Is_High_Bound); 5086 5087 New_Exp := New_Copy_Tree (Exp); 5088 Remove_Checks (New_Exp); 5089 return New_Exp; 5090 end Duplicate_Subexpr_No_Checks; 5091 5092 ----------------------------------- 5093 -- Duplicate_Subexpr_Move_Checks -- 5094 ----------------------------------- 5095 5096 function Duplicate_Subexpr_Move_Checks 5097 (Exp : Node_Id; 5098 Name_Req : Boolean := False; 5099 Renaming_Req : Boolean := False) return Node_Id 5100 is 5101 New_Exp : Node_Id; 5102 5103 begin 5104 Remove_Side_Effects (Exp, Name_Req, Renaming_Req); 5105 New_Exp := New_Copy_Tree (Exp); 5106 Remove_Checks (Exp); 5107 return New_Exp; 5108 end Duplicate_Subexpr_Move_Checks; 5109 5110 ------------------------- 5111 -- Enclosing_Init_Proc -- 5112 ------------------------- 5113 5114 function Enclosing_Init_Proc return Entity_Id is 5115 S : Entity_Id; 5116 5117 begin 5118 S := Current_Scope; 5119 while Present (S) and then S /= Standard_Standard loop 5120 if Is_Init_Proc (S) then 5121 return S; 5122 else 5123 S := Scope (S); 5124 end if; 5125 end loop; 5126 5127 return Empty; 5128 end Enclosing_Init_Proc; 5129 5130 -------------------- 5131 -- Ensure_Defined -- 5132 -------------------- 5133 5134 procedure Ensure_Defined (Typ : Entity_Id; N : Node_Id) is 5135 IR : Node_Id; 5136 5137 begin 5138 -- An itype reference must only be created if this is a local itype, so 5139 -- that gigi can elaborate it on the proper objstack. 5140 5141 if Is_Itype (Typ) and then Scope (Typ) = Current_Scope then 5142 IR := Make_Itype_Reference (Sloc (N)); 5143 Set_Itype (IR, Typ); 5144 Insert_Action (N, IR); 5145 end if; 5146 end Ensure_Defined; 5147 5148 -------------------- 5149 -- Entry_Names_OK -- 5150 -------------------- 5151 5152 function Entry_Names_OK return Boolean is 5153 begin 5154 return 5155 not Restricted_Profile 5156 and then not Global_Discard_Names 5157 and then not Restriction_Active (No_Implicit_Heap_Allocations) 5158 and then not Restriction_Active (No_Local_Allocators); 5159 end Entry_Names_OK; 5160 5161 ------------------- 5162 -- Evaluate_Name -- 5163 ------------------- 5164 5165 procedure Evaluate_Name (Nam : Node_Id) is 5166 begin 5167 case Nkind (Nam) is 5168 -- For an aggregate, force its evaluation 5169 5170 when N_Aggregate => 5171 Force_Evaluation (Nam); 5172 5173 -- For an attribute reference or an indexed component, evaluate the 5174 -- prefix, which is itself a name, recursively, and then force the 5175 -- evaluation of all the subscripts (or attribute expressions). 5176 5177 when N_Attribute_Reference 5178 | N_Indexed_Component 5179 => 5180 Evaluate_Name (Prefix (Nam)); 5181 5182 declare 5183 E : Node_Id; 5184 5185 begin 5186 E := First (Expressions (Nam)); 5187 while Present (E) loop 5188 Force_Evaluation (E); 5189 5190 if Is_Rewrite_Substitution (E) then 5191 Set_Do_Range_Check 5192 (E, Do_Range_Check (Original_Node (E))); 5193 end if; 5194 5195 Next (E); 5196 end loop; 5197 end; 5198 5199 -- For an explicit dereference, we simply force the evaluation of 5200 -- the name expression. The dereference provides a value that is the 5201 -- address for the renamed object, and it is precisely this value 5202 -- that we want to preserve. 5203 5204 when N_Explicit_Dereference => 5205 Force_Evaluation (Prefix (Nam)); 5206 5207 -- For a function call, we evaluate the call; same for an operator 5208 5209 when N_Function_Call 5210 | N_Op 5211 => 5212 Force_Evaluation (Nam); 5213 5214 -- For a qualified expression, we evaluate the expression 5215 5216 when N_Qualified_Expression => 5217 Evaluate_Name (Expression (Nam)); 5218 5219 -- For a selected component, we simply evaluate the prefix 5220 5221 when N_Selected_Component => 5222 Evaluate_Name (Prefix (Nam)); 5223 5224 -- For a slice, we evaluate the prefix, as for the indexed component 5225 -- case and then, if there is a range present, either directly or as 5226 -- the constraint of a discrete subtype indication, we evaluate the 5227 -- two bounds of this range. 5228 5229 when N_Slice => 5230 Evaluate_Name (Prefix (Nam)); 5231 Evaluate_Slice_Bounds (Nam); 5232 5233 -- For a type conversion, the expression of the conversion must be 5234 -- the name of an object, and we simply need to evaluate this name. 5235 5236 when N_Type_Conversion => 5237 Evaluate_Name (Expression (Nam)); 5238 5239 -- The remaining cases are direct name and character literal. In all 5240 -- these cases, we do nothing, since we want to reevaluate each time 5241 -- the renamed object is used. ??? There are more remaining cases, at 5242 -- least in the GNATprove_Mode, where this routine is called in more 5243 -- contexts than in GNAT. 5244 5245 when others => 5246 null; 5247 end case; 5248 end Evaluate_Name; 5249 5250 --------------------------- 5251 -- Evaluate_Slice_Bounds -- 5252 --------------------------- 5253 5254 procedure Evaluate_Slice_Bounds (Slice : Node_Id) is 5255 DR : constant Node_Id := Discrete_Range (Slice); 5256 Constr : Node_Id; 5257 Rexpr : Node_Id; 5258 5259 begin 5260 if Nkind (DR) = N_Range then 5261 Force_Evaluation (Low_Bound (DR)); 5262 Force_Evaluation (High_Bound (DR)); 5263 5264 elsif Nkind (DR) = N_Subtype_Indication then 5265 Constr := Constraint (DR); 5266 5267 if Nkind (Constr) = N_Range_Constraint then 5268 Rexpr := Range_Expression (Constr); 5269 5270 Force_Evaluation (Low_Bound (Rexpr)); 5271 Force_Evaluation (High_Bound (Rexpr)); 5272 end if; 5273 end if; 5274 end Evaluate_Slice_Bounds; 5275 5276 --------------------- 5277 -- Evolve_And_Then -- 5278 --------------------- 5279 5280 procedure Evolve_And_Then (Cond : in out Node_Id; Cond1 : Node_Id) is 5281 begin 5282 if No (Cond) then 5283 Cond := Cond1; 5284 else 5285 Cond := 5286 Make_And_Then (Sloc (Cond1), 5287 Left_Opnd => Cond, 5288 Right_Opnd => Cond1); 5289 end if; 5290 end Evolve_And_Then; 5291 5292 -------------------- 5293 -- Evolve_Or_Else -- 5294 -------------------- 5295 5296 procedure Evolve_Or_Else (Cond : in out Node_Id; Cond1 : Node_Id) is 5297 begin 5298 if No (Cond) then 5299 Cond := Cond1; 5300 else 5301 Cond := 5302 Make_Or_Else (Sloc (Cond1), 5303 Left_Opnd => Cond, 5304 Right_Opnd => Cond1); 5305 end if; 5306 end Evolve_Or_Else; 5307 5308 ----------------------------------------- 5309 -- Expand_Static_Predicates_In_Choices -- 5310 ----------------------------------------- 5311 5312 procedure Expand_Static_Predicates_In_Choices (N : Node_Id) is 5313 pragma Assert (Nkind (N) in N_Case_Statement_Alternative | N_Variant); 5314 5315 Choices : constant List_Id := Discrete_Choices (N); 5316 5317 Choice : Node_Id; 5318 Next_C : Node_Id; 5319 P : Node_Id; 5320 C : Node_Id; 5321 5322 begin 5323 Choice := First (Choices); 5324 while Present (Choice) loop 5325 Next_C := Next (Choice); 5326 5327 -- Check for name of subtype with static predicate 5328 5329 if Is_Entity_Name (Choice) 5330 and then Is_Type (Entity (Choice)) 5331 and then Has_Predicates (Entity (Choice)) 5332 then 5333 -- Loop through entries in predicate list, converting to choices 5334 -- and inserting in the list before the current choice. Note that 5335 -- if the list is empty, corresponding to a False predicate, then 5336 -- no choices are inserted. 5337 5338 P := First (Static_Discrete_Predicate (Entity (Choice))); 5339 while Present (P) loop 5340 5341 -- If low bound and high bounds are equal, copy simple choice 5342 5343 if Expr_Value (Low_Bound (P)) = Expr_Value (High_Bound (P)) then 5344 C := New_Copy (Low_Bound (P)); 5345 5346 -- Otherwise copy a range 5347 5348 else 5349 C := New_Copy (P); 5350 end if; 5351 5352 -- Change Sloc to referencing choice (rather than the Sloc of 5353 -- the predicate declaration element itself). 5354 5355 Set_Sloc (C, Sloc (Choice)); 5356 Insert_Before (Choice, C); 5357 Next (P); 5358 end loop; 5359 5360 -- Delete the predicated entry 5361 5362 Remove (Choice); 5363 end if; 5364 5365 -- Move to next choice to check 5366 5367 Choice := Next_C; 5368 end loop; 5369 5370 Set_Has_SP_Choice (N, False); 5371 end Expand_Static_Predicates_In_Choices; 5372 5373 ------------------------------ 5374 -- Expand_Subtype_From_Expr -- 5375 ------------------------------ 5376 5377 -- This function is applicable for both static and dynamic allocation of 5378 -- objects which are constrained by an initial expression. Basically it 5379 -- transforms an unconstrained subtype indication into a constrained one. 5380 5381 -- The expression may also be transformed in certain cases in order to 5382 -- avoid multiple evaluation. In the static allocation case, the general 5383 -- scheme is: 5384 5385 -- Val : T := Expr; 5386 5387 -- is transformed into 5388 5389 -- Val : Constrained_Subtype_Of_T := Maybe_Modified_Expr; 5390 -- 5391 -- Here are the main cases : 5392 -- 5393 -- <if Expr is a Slice> 5394 -- Val : T ([Index_Subtype (Expr)]) := Expr; 5395 -- 5396 -- <elsif Expr is a String Literal> 5397 -- Val : T (T'First .. T'First + Length (string literal) - 1) := Expr; 5398 -- 5399 -- <elsif Expr is Constrained> 5400 -- subtype T is Type_Of_Expr 5401 -- Val : T := Expr; 5402 -- 5403 -- <elsif Expr is an entity_name> 5404 -- Val : T (constraints taken from Expr) := Expr; 5405 -- 5406 -- <else> 5407 -- type Axxx is access all T; 5408 -- Rval : Axxx := Expr'ref; 5409 -- Val : T (constraints taken from Rval) := Rval.all; 5410 5411 -- ??? note: when the Expression is allocated in the secondary stack 5412 -- we could use it directly instead of copying it by declaring 5413 -- Val : T (...) renames Rval.all 5414 5415 procedure Expand_Subtype_From_Expr 5416 (N : Node_Id; 5417 Unc_Type : Entity_Id; 5418 Subtype_Indic : Node_Id; 5419 Exp : Node_Id; 5420 Related_Id : Entity_Id := Empty) 5421 is 5422 Loc : constant Source_Ptr := Sloc (N); 5423 Exp_Typ : constant Entity_Id := Etype (Exp); 5424 T : Entity_Id; 5425 5426 begin 5427 -- In general we cannot build the subtype if expansion is disabled, 5428 -- because internal entities may not have been defined. However, to 5429 -- avoid some cascaded errors, we try to continue when the expression is 5430 -- an array (or string), because it is safe to compute the bounds. It is 5431 -- in fact required to do so even in a generic context, because there 5432 -- may be constants that depend on the bounds of a string literal, both 5433 -- standard string types and more generally arrays of characters. 5434 5435 -- In GNATprove mode, these extra subtypes are not needed, unless Exp is 5436 -- a static expression. In that case, the subtype will be constrained 5437 -- while the original type might be unconstrained, so expanding the type 5438 -- is necessary both for passing legality checks in GNAT and for precise 5439 -- analysis in GNATprove. 5440 5441 if GNATprove_Mode and then not Is_Static_Expression (Exp) then 5442 return; 5443 end if; 5444 5445 if not Expander_Active 5446 and then (No (Etype (Exp)) or else not Is_String_Type (Etype (Exp))) 5447 then 5448 return; 5449 end if; 5450 5451 if Nkind (Exp) = N_Slice then 5452 declare 5453 Slice_Type : constant Entity_Id := Etype (First_Index (Exp_Typ)); 5454 5455 begin 5456 Rewrite (Subtype_Indic, 5457 Make_Subtype_Indication (Loc, 5458 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc), 5459 Constraint => 5460 Make_Index_Or_Discriminant_Constraint (Loc, 5461 Constraints => New_List 5462 (New_Occurrence_Of (Slice_Type, Loc))))); 5463 5464 -- This subtype indication may be used later for constraint checks 5465 -- we better make sure that if a variable was used as a bound of 5466 -- the original slice, its value is frozen. 5467 5468 Evaluate_Slice_Bounds (Exp); 5469 end; 5470 5471 elsif Ekind (Exp_Typ) = E_String_Literal_Subtype then 5472 Rewrite (Subtype_Indic, 5473 Make_Subtype_Indication (Loc, 5474 Subtype_Mark => New_Occurrence_Of (Unc_Type, Loc), 5475 Constraint => 5476 Make_Index_Or_Discriminant_Constraint (Loc, 5477 Constraints => New_List ( 5478 Make_Literal_Range (Loc, 5479 Literal_Typ => Exp_Typ))))); 5480 5481 -- If the type of the expression is an internally generated type it 5482 -- may not be necessary to create a new subtype. However there are two 5483 -- exceptions: references to the current instances, and aliased array 5484 -- object declarations for which the back end has to create a template. 5485 5486 elsif Is_Constrained (Exp_Typ) 5487 and then not Is_Class_Wide_Type (Unc_Type) 5488 and then 5489 (Nkind (N) /= N_Object_Declaration 5490 or else not Is_Entity_Name (Expression (N)) 5491 or else not Comes_From_Source (Entity (Expression (N))) 5492 or else not Is_Array_Type (Exp_Typ) 5493 or else not Aliased_Present (N)) 5494 then 5495 if Is_Itype (Exp_Typ) then 5496 5497 -- Within an initialization procedure, a selected component 5498 -- denotes a component of the enclosing record, and it appears as 5499 -- an actual in a call to its own initialization procedure. If 5500 -- this component depends on the outer discriminant, we must 5501 -- generate the proper actual subtype for it. 5502 5503 if Nkind (Exp) = N_Selected_Component 5504 and then Within_Init_Proc 5505 then 5506 declare 5507 Decl : constant Node_Id := 5508 Build_Actual_Subtype_Of_Component (Exp_Typ, Exp); 5509 begin 5510 if Present (Decl) then 5511 Insert_Action (N, Decl); 5512 T := Defining_Identifier (Decl); 5513 else 5514 T := Exp_Typ; 5515 end if; 5516 end; 5517 5518 -- No need to generate a new subtype 5519 5520 else 5521 T := Exp_Typ; 5522 end if; 5523 5524 else 5525 T := Make_Temporary (Loc, 'T'); 5526 5527 Insert_Action (N, 5528 Make_Subtype_Declaration (Loc, 5529 Defining_Identifier => T, 5530 Subtype_Indication => New_Occurrence_Of (Exp_Typ, Loc))); 5531 5532 -- This type is marked as an itype even though it has an explicit 5533 -- declaration since otherwise Is_Generic_Actual_Type can get 5534 -- set, resulting in the generation of spurious errors. (See 5535 -- sem_ch8.Analyze_Package_Renaming and sem_type.covers) 5536 5537 Set_Is_Itype (T); 5538 Set_Associated_Node_For_Itype (T, Exp); 5539 end if; 5540 5541 Rewrite (Subtype_Indic, New_Occurrence_Of (T, Loc)); 5542 5543 -- Nothing needs to be done for private types with unknown discriminants 5544 -- if the underlying type is not an unconstrained composite type or it 5545 -- is an unchecked union. 5546 5547 elsif Is_Private_Type (Unc_Type) 5548 and then Has_Unknown_Discriminants (Unc_Type) 5549 and then (not Is_Composite_Type (Underlying_Type (Unc_Type)) 5550 or else Is_Constrained (Underlying_Type (Unc_Type)) 5551 or else Is_Unchecked_Union (Underlying_Type (Unc_Type))) 5552 then 5553 null; 5554 5555 -- Case of derived type with unknown discriminants where the parent type 5556 -- also has unknown discriminants. 5557 5558 elsif Is_Record_Type (Unc_Type) 5559 and then not Is_Class_Wide_Type (Unc_Type) 5560 and then Has_Unknown_Discriminants (Unc_Type) 5561 and then Has_Unknown_Discriminants (Underlying_Type (Unc_Type)) 5562 then 5563 -- Nothing to be done if no underlying record view available 5564 5565 -- If this is a limited type derived from a type with unknown 5566 -- discriminants, do not expand either, so that subsequent expansion 5567 -- of the call can add build-in-place parameters to call. 5568 5569 if No (Underlying_Record_View (Unc_Type)) 5570 or else Is_Limited_Type (Unc_Type) 5571 then 5572 null; 5573 5574 -- Otherwise use the Underlying_Record_View to create the proper 5575 -- constrained subtype for an object of a derived type with unknown 5576 -- discriminants. 5577 5578 else 5579 Remove_Side_Effects (Exp); 5580 Rewrite (Subtype_Indic, 5581 Make_Subtype_From_Expr (Exp, Underlying_Record_View (Unc_Type))); 5582 end if; 5583 5584 -- Renamings of class-wide interface types require no equivalent 5585 -- constrained type declarations because we only need to reference 5586 -- the tag component associated with the interface. The same is 5587 -- presumably true for class-wide types in general, so this test 5588 -- is broadened to include all class-wide renamings, which also 5589 -- avoids cases of unbounded recursion in Remove_Side_Effects. 5590 -- (Is this really correct, or are there some cases of class-wide 5591 -- renamings that require action in this procedure???) 5592 5593 elsif Present (N) 5594 and then Nkind (N) = N_Object_Renaming_Declaration 5595 and then Is_Class_Wide_Type (Unc_Type) 5596 then 5597 null; 5598 5599 -- In Ada 95 nothing to be done if the type of the expression is limited 5600 -- because in this case the expression cannot be copied, and its use can 5601 -- only be by reference. 5602 5603 -- In Ada 2005 the context can be an object declaration whose expression 5604 -- is a function that returns in place. If the nominal subtype has 5605 -- unknown discriminants, the call still provides constraints on the 5606 -- object, and we have to create an actual subtype from it. 5607 5608 -- If the type is class-wide, the expression is dynamically tagged and 5609 -- we do not create an actual subtype either. Ditto for an interface. 5610 -- For now this applies only if the type is immutably limited, and the 5611 -- function being called is build-in-place. This will have to be revised 5612 -- when build-in-place functions are generalized to other types. 5613 5614 elsif Is_Limited_View (Exp_Typ) 5615 and then 5616 (Is_Class_Wide_Type (Exp_Typ) 5617 or else Is_Interface (Exp_Typ) 5618 or else not Has_Unknown_Discriminants (Exp_Typ) 5619 or else not Is_Composite_Type (Unc_Type)) 5620 then 5621 null; 5622 5623 -- For limited objects initialized with build-in-place function calls, 5624 -- nothing to be done; otherwise we prematurely introduce an N_Reference 5625 -- node in the expression initializing the object, which breaks the 5626 -- circuitry that detects and adds the additional arguments to the 5627 -- called function. 5628 5629 elsif Is_Build_In_Place_Function_Call (Exp) then 5630 null; 5631 5632 -- If the expression is an uninitialized aggregate, no need to build 5633 -- a subtype from the expression, because this may require the use of 5634 -- dynamic memory to create the object. 5635 5636 elsif Is_Uninitialized_Aggregate (Exp, Exp_Typ) then 5637 Rewrite (Subtype_Indic, New_Occurrence_Of (Etype (Exp), Sloc (N))); 5638 if Nkind (N) = N_Object_Declaration then 5639 Set_Expression (N, Empty); 5640 Set_No_Initialization (N); 5641 end if; 5642 5643 else 5644 Remove_Side_Effects (Exp); 5645 Rewrite (Subtype_Indic, 5646 Make_Subtype_From_Expr (Exp, Unc_Type, Related_Id)); 5647 end if; 5648 end Expand_Subtype_From_Expr; 5649 5650 --------------------------------------------- 5651 -- Expression_Contains_Primitives_Calls_Of -- 5652 --------------------------------------------- 5653 5654 function Expression_Contains_Primitives_Calls_Of 5655 (Expr : Node_Id; 5656 Typ : Entity_Id) return Boolean 5657 is 5658 U_Typ : constant Entity_Id := Unique_Entity (Typ); 5659 5660 Calls_OK : Boolean := False; 5661 -- This flag is set to True when expression Expr contains at least one 5662 -- call to a nondispatching primitive function of Typ. 5663 5664 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result; 5665 -- Search for nondispatching calls to primitive functions of type Typ 5666 5667 ---------------------------- 5668 -- Search_Primitive_Calls -- 5669 ---------------------------- 5670 5671 function Search_Primitive_Calls (N : Node_Id) return Traverse_Result is 5672 Disp_Typ : Entity_Id; 5673 Subp : Entity_Id; 5674 5675 begin 5676 -- Detect a function call that could denote a nondispatching 5677 -- primitive of the input type. 5678 5679 if Nkind (N) = N_Function_Call 5680 and then Is_Entity_Name (Name (N)) 5681 then 5682 Subp := Entity (Name (N)); 5683 5684 -- Do not consider function calls with a controlling argument, as 5685 -- those are always dispatching calls. 5686 5687 if Is_Dispatching_Operation (Subp) 5688 and then No (Controlling_Argument (N)) 5689 then 5690 Disp_Typ := Find_Dispatching_Type (Subp); 5691 5692 -- To qualify as a suitable primitive, the dispatching type of 5693 -- the function must be the input type. 5694 5695 if Present (Disp_Typ) 5696 and then Unique_Entity (Disp_Typ) = U_Typ 5697 then 5698 Calls_OK := True; 5699 5700 -- There is no need to continue the traversal, as one such 5701 -- call suffices. 5702 5703 return Abandon; 5704 end if; 5705 end if; 5706 end if; 5707 5708 return OK; 5709 end Search_Primitive_Calls; 5710 5711 procedure Search_Calls is new Traverse_Proc (Search_Primitive_Calls); 5712 5713 -- Start of processing for Expression_Contains_Primitives_Calls_Of_Type 5714 5715 begin 5716 Search_Calls (Expr); 5717 return Calls_OK; 5718 end Expression_Contains_Primitives_Calls_Of; 5719 5720 ---------------------- 5721 -- Finalize_Address -- 5722 ---------------------- 5723 5724 function Finalize_Address (Typ : Entity_Id) return Entity_Id is 5725 Btyp : constant Entity_Id := Base_Type (Typ); 5726 Utyp : Entity_Id := Typ; 5727 5728 begin 5729 -- Handle protected class-wide or task class-wide types 5730 5731 if Is_Class_Wide_Type (Utyp) then 5732 if Is_Concurrent_Type (Root_Type (Utyp)) then 5733 Utyp := Root_Type (Utyp); 5734 5735 elsif Is_Private_Type (Root_Type (Utyp)) 5736 and then Present (Full_View (Root_Type (Utyp))) 5737 and then Is_Concurrent_Type (Full_View (Root_Type (Utyp))) 5738 then 5739 Utyp := Full_View (Root_Type (Utyp)); 5740 end if; 5741 end if; 5742 5743 -- Handle private types 5744 5745 if Is_Private_Type (Utyp) and then Present (Full_View (Utyp)) then 5746 Utyp := Full_View (Utyp); 5747 end if; 5748 5749 -- Handle protected and task types 5750 5751 if Is_Concurrent_Type (Utyp) 5752 and then Present (Corresponding_Record_Type (Utyp)) 5753 then 5754 Utyp := Corresponding_Record_Type (Utyp); 5755 end if; 5756 5757 Utyp := Underlying_Type (Base_Type (Utyp)); 5758 5759 -- Deal with untagged derivation of private views. If the parent is 5760 -- now known to be protected, the finalization routine is the one 5761 -- defined on the corresponding record of the ancestor (corresponding 5762 -- records do not automatically inherit operations, but maybe they 5763 -- should???) 5764 5765 if Is_Untagged_Derivation (Btyp) then 5766 if Is_Protected_Type (Btyp) then 5767 Utyp := Corresponding_Record_Type (Root_Type (Btyp)); 5768 5769 else 5770 Utyp := Underlying_Type (Root_Type (Btyp)); 5771 5772 if Is_Protected_Type (Utyp) then 5773 Utyp := Corresponding_Record_Type (Utyp); 5774 end if; 5775 end if; 5776 end if; 5777 5778 -- If the underlying_type is a subtype, we are dealing with the 5779 -- completion of a private type. We need to access the base type and 5780 -- generate a conversion to it. 5781 5782 if Utyp /= Base_Type (Utyp) then 5783 pragma Assert (Is_Private_Type (Typ)); 5784 5785 Utyp := Base_Type (Utyp); 5786 end if; 5787 5788 -- When dealing with an internally built full view for a type with 5789 -- unknown discriminants, use the original record type. 5790 5791 if Is_Underlying_Record_View (Utyp) then 5792 Utyp := Etype (Utyp); 5793 end if; 5794 5795 return TSS (Utyp, TSS_Finalize_Address); 5796 end Finalize_Address; 5797 5798 ------------------------ 5799 -- Find_Interface_ADT -- 5800 ------------------------ 5801 5802 function Find_Interface_ADT 5803 (T : Entity_Id; 5804 Iface : Entity_Id) return Elmt_Id 5805 is 5806 ADT : Elmt_Id; 5807 Typ : Entity_Id := T; 5808 5809 begin 5810 pragma Assert (Is_Interface (Iface)); 5811 5812 -- Handle private types 5813 5814 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then 5815 Typ := Full_View (Typ); 5816 end if; 5817 5818 -- Handle access types 5819 5820 if Is_Access_Type (Typ) then 5821 Typ := Designated_Type (Typ); 5822 end if; 5823 5824 -- Handle task and protected types implementing interfaces 5825 5826 if Is_Concurrent_Type (Typ) then 5827 Typ := Corresponding_Record_Type (Typ); 5828 end if; 5829 5830 pragma Assert 5831 (not Is_Class_Wide_Type (Typ) 5832 and then Ekind (Typ) /= E_Incomplete_Type); 5833 5834 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then 5835 return First_Elmt (Access_Disp_Table (Typ)); 5836 5837 else 5838 ADT := Next_Elmt (Next_Elmt (First_Elmt (Access_Disp_Table (Typ)))); 5839 while Present (ADT) 5840 and then Present (Related_Type (Node (ADT))) 5841 and then Related_Type (Node (ADT)) /= Iface 5842 and then not Is_Ancestor (Iface, Related_Type (Node (ADT)), 5843 Use_Full_View => True) 5844 loop 5845 Next_Elmt (ADT); 5846 end loop; 5847 5848 pragma Assert (Present (Related_Type (Node (ADT)))); 5849 return ADT; 5850 end if; 5851 end Find_Interface_ADT; 5852 5853 ------------------------ 5854 -- Find_Interface_Tag -- 5855 ------------------------ 5856 5857 function Find_Interface_Tag 5858 (T : Entity_Id; 5859 Iface : Entity_Id) return Entity_Id 5860 is 5861 AI_Tag : Entity_Id := Empty; 5862 Found : Boolean := False; 5863 Typ : Entity_Id := T; 5864 5865 procedure Find_Tag (Typ : Entity_Id); 5866 -- Internal subprogram used to recursively climb to the ancestors 5867 5868 -------------- 5869 -- Find_Tag -- 5870 -------------- 5871 5872 procedure Find_Tag (Typ : Entity_Id) is 5873 AI_Elmt : Elmt_Id; 5874 AI : Node_Id; 5875 5876 begin 5877 -- This routine does not handle the case in which the interface is an 5878 -- ancestor of Typ. That case is handled by the enclosing subprogram. 5879 5880 pragma Assert (Typ /= Iface); 5881 5882 -- Climb to the root type handling private types 5883 5884 if Present (Full_View (Etype (Typ))) then 5885 if Full_View (Etype (Typ)) /= Typ then 5886 Find_Tag (Full_View (Etype (Typ))); 5887 end if; 5888 5889 elsif Etype (Typ) /= Typ then 5890 Find_Tag (Etype (Typ)); 5891 end if; 5892 5893 -- Traverse the list of interfaces implemented by the type 5894 5895 if not Found 5896 and then Present (Interfaces (Typ)) 5897 and then not (Is_Empty_Elmt_List (Interfaces (Typ))) 5898 then 5899 -- Skip the tag associated with the primary table 5900 5901 AI_Tag := Next_Tag_Component (First_Tag_Component (Typ)); 5902 pragma Assert (Present (AI_Tag)); 5903 5904 AI_Elmt := First_Elmt (Interfaces (Typ)); 5905 while Present (AI_Elmt) loop 5906 AI := Node (AI_Elmt); 5907 5908 if AI = Iface 5909 or else Is_Ancestor (Iface, AI, Use_Full_View => True) 5910 then 5911 Found := True; 5912 return; 5913 end if; 5914 5915 AI_Tag := Next_Tag_Component (AI_Tag); 5916 Next_Elmt (AI_Elmt); 5917 end loop; 5918 end if; 5919 end Find_Tag; 5920 5921 -- Start of processing for Find_Interface_Tag 5922 5923 begin 5924 pragma Assert (Is_Interface (Iface)); 5925 5926 -- Handle access types 5927 5928 if Is_Access_Type (Typ) then 5929 Typ := Designated_Type (Typ); 5930 end if; 5931 5932 -- Handle class-wide types 5933 5934 if Is_Class_Wide_Type (Typ) then 5935 Typ := Root_Type (Typ); 5936 end if; 5937 5938 -- Handle private types 5939 5940 if Has_Private_Declaration (Typ) and then Present (Full_View (Typ)) then 5941 Typ := Full_View (Typ); 5942 end if; 5943 5944 -- Handle entities from the limited view 5945 5946 if Ekind (Typ) = E_Incomplete_Type then 5947 pragma Assert (Present (Non_Limited_View (Typ))); 5948 Typ := Non_Limited_View (Typ); 5949 end if; 5950 5951 -- Handle task and protected types implementing interfaces 5952 5953 if Is_Concurrent_Type (Typ) then 5954 Typ := Corresponding_Record_Type (Typ); 5955 end if; 5956 5957 -- If the interface is an ancestor of the type, then it shared the 5958 -- primary dispatch table. 5959 5960 if Is_Ancestor (Iface, Typ, Use_Full_View => True) then 5961 return First_Tag_Component (Typ); 5962 5963 -- Otherwise we need to search for its associated tag component 5964 5965 else 5966 Find_Tag (Typ); 5967 return AI_Tag; 5968 end if; 5969 end Find_Interface_Tag; 5970 5971 --------------------------- 5972 -- Find_Optional_Prim_Op -- 5973 --------------------------- 5974 5975 function Find_Optional_Prim_Op 5976 (T : Entity_Id; Name : Name_Id) return Entity_Id 5977 is 5978 Prim : Elmt_Id; 5979 Typ : Entity_Id := T; 5980 Op : Entity_Id; 5981 5982 begin 5983 if Is_Class_Wide_Type (Typ) then 5984 Typ := Root_Type (Typ); 5985 end if; 5986 5987 Typ := Underlying_Type (Typ); 5988 5989 -- Loop through primitive operations 5990 5991 Prim := First_Elmt (Primitive_Operations (Typ)); 5992 while Present (Prim) loop 5993 Op := Node (Prim); 5994 5995 -- We can retrieve primitive operations by name if it is an internal 5996 -- name. For equality we must check that both of its operands have 5997 -- the same type, to avoid confusion with user-defined equalities 5998 -- than may have a asymmetric signature. 5999 6000 exit when Chars (Op) = Name 6001 and then 6002 (Name /= Name_Op_Eq 6003 or else Etype (First_Formal (Op)) = Etype (Last_Formal (Op))); 6004 6005 Next_Elmt (Prim); 6006 end loop; 6007 6008 return Node (Prim); -- Empty if not found 6009 end Find_Optional_Prim_Op; 6010 6011 --------------------------- 6012 -- Find_Optional_Prim_Op -- 6013 --------------------------- 6014 6015 function Find_Optional_Prim_Op 6016 (T : Entity_Id; 6017 Name : TSS_Name_Type) return Entity_Id 6018 is 6019 Inher_Op : Entity_Id := Empty; 6020 Own_Op : Entity_Id := Empty; 6021 Prim_Elmt : Elmt_Id; 6022 Prim_Id : Entity_Id; 6023 Typ : Entity_Id := T; 6024 6025 begin 6026 if Is_Class_Wide_Type (Typ) then 6027 Typ := Root_Type (Typ); 6028 end if; 6029 6030 Typ := Underlying_Type (Typ); 6031 6032 -- This search is based on the assertion that the dispatching version 6033 -- of the TSS routine always precedes the real primitive. 6034 6035 Prim_Elmt := First_Elmt (Primitive_Operations (Typ)); 6036 while Present (Prim_Elmt) loop 6037 Prim_Id := Node (Prim_Elmt); 6038 6039 if Is_TSS (Prim_Id, Name) then 6040 if Present (Alias (Prim_Id)) then 6041 Inher_Op := Prim_Id; 6042 else 6043 Own_Op := Prim_Id; 6044 end if; 6045 end if; 6046 6047 Next_Elmt (Prim_Elmt); 6048 end loop; 6049 6050 if Present (Own_Op) then 6051 return Own_Op; 6052 elsif Present (Inher_Op) then 6053 return Inher_Op; 6054 else 6055 return Empty; 6056 end if; 6057 end Find_Optional_Prim_Op; 6058 6059 ------------------ 6060 -- Find_Prim_Op -- 6061 ------------------ 6062 6063 function Find_Prim_Op 6064 (T : Entity_Id; Name : Name_Id) return Entity_Id 6065 is 6066 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name); 6067 begin 6068 if No (Result) then 6069 raise Program_Error; 6070 end if; 6071 6072 return Result; 6073 end Find_Prim_Op; 6074 6075 ------------------ 6076 -- Find_Prim_Op -- 6077 ------------------ 6078 6079 function Find_Prim_Op 6080 (T : Entity_Id; 6081 Name : TSS_Name_Type) return Entity_Id 6082 is 6083 Result : constant Entity_Id := Find_Optional_Prim_Op (T, Name); 6084 begin 6085 if No (Result) then 6086 raise Program_Error; 6087 end if; 6088 6089 return Result; 6090 end Find_Prim_Op; 6091 6092 ---------------------------- 6093 -- Find_Protection_Object -- 6094 ---------------------------- 6095 6096 function Find_Protection_Object (Scop : Entity_Id) return Entity_Id is 6097 S : Entity_Id; 6098 6099 begin 6100 S := Scop; 6101 while Present (S) loop 6102 if Ekind (S) in E_Entry | E_Entry_Family | E_Function | E_Procedure 6103 and then Present (Protection_Object (S)) 6104 then 6105 return Protection_Object (S); 6106 end if; 6107 6108 S := Scope (S); 6109 end loop; 6110 6111 -- If we do not find a Protection object in the scope chain, then 6112 -- something has gone wrong, most likely the object was never created. 6113 6114 raise Program_Error; 6115 end Find_Protection_Object; 6116 6117 -------------------------- 6118 -- Find_Protection_Type -- 6119 -------------------------- 6120 6121 function Find_Protection_Type (Conc_Typ : Entity_Id) return Entity_Id is 6122 Comp : Entity_Id; 6123 Typ : Entity_Id := Conc_Typ; 6124 6125 begin 6126 if Is_Concurrent_Type (Typ) then 6127 Typ := Corresponding_Record_Type (Typ); 6128 end if; 6129 6130 -- Since restriction violations are not considered serious errors, the 6131 -- expander remains active, but may leave the corresponding record type 6132 -- malformed. In such cases, component _object is not available so do 6133 -- not look for it. 6134 6135 if not Analyzed (Typ) then 6136 return Empty; 6137 end if; 6138 6139 Comp := First_Component (Typ); 6140 while Present (Comp) loop 6141 if Chars (Comp) = Name_uObject then 6142 return Base_Type (Etype (Comp)); 6143 end if; 6144 6145 Next_Component (Comp); 6146 end loop; 6147 6148 -- The corresponding record of a protected type should always have an 6149 -- _object field. 6150 6151 raise Program_Error; 6152 end Find_Protection_Type; 6153 6154 ----------------------- 6155 -- Find_Hook_Context -- 6156 ----------------------- 6157 6158 function Find_Hook_Context (N : Node_Id) return Node_Id is 6159 Par : Node_Id; 6160 Top : Node_Id; 6161 6162 Wrapped_Node : Node_Id; 6163 -- Note: if we are in a transient scope, we want to reuse it as 6164 -- the context for actions insertion, if possible. But if N is itself 6165 -- part of the stored actions for the current transient scope, 6166 -- then we need to insert at the appropriate (inner) location in 6167 -- the not as an action on Node_To_Be_Wrapped. 6168 6169 In_Cond_Expr : constant Boolean := Within_Case_Or_If_Expression (N); 6170 6171 begin 6172 -- When the node is inside a case/if expression, the lifetime of any 6173 -- temporary controlled object is extended. Find a suitable insertion 6174 -- node by locating the topmost case or if expressions. 6175 6176 if In_Cond_Expr then 6177 Par := N; 6178 Top := N; 6179 while Present (Par) loop 6180 if Nkind (Original_Node (Par)) in 6181 N_Case_Expression | N_If_Expression 6182 then 6183 Top := Par; 6184 6185 -- Prevent the search from going too far 6186 6187 elsif Is_Body_Or_Package_Declaration (Par) then 6188 exit; 6189 end if; 6190 6191 Par := Parent (Par); 6192 end loop; 6193 6194 -- The topmost case or if expression is now recovered, but it may 6195 -- still not be the correct place to add generated code. Climb to 6196 -- find a parent that is part of a declarative or statement list, 6197 -- and is not a list of actuals in a call. 6198 6199 Par := Top; 6200 while Present (Par) loop 6201 if Is_List_Member (Par) 6202 and then Nkind (Par) not in N_Component_Association 6203 | N_Discriminant_Association 6204 | N_Parameter_Association 6205 | N_Pragma_Argument_Association 6206 and then Nkind (Parent (Par)) not in N_Function_Call 6207 | N_Procedure_Call_Statement 6208 | N_Entry_Call_Statement 6209 6210 then 6211 return Par; 6212 6213 -- Prevent the search from going too far 6214 6215 elsif Is_Body_Or_Package_Declaration (Par) then 6216 exit; 6217 end if; 6218 6219 Par := Parent (Par); 6220 end loop; 6221 6222 return Par; 6223 6224 else 6225 Par := N; 6226 while Present (Par) loop 6227 6228 -- Keep climbing past various operators 6229 6230 if Nkind (Parent (Par)) in N_Op 6231 or else Nkind (Parent (Par)) in N_And_Then | N_Or_Else 6232 then 6233 Par := Parent (Par); 6234 else 6235 exit; 6236 end if; 6237 end loop; 6238 6239 Top := Par; 6240 6241 -- The node may be located in a pragma in which case return the 6242 -- pragma itself: 6243 6244 -- pragma Precondition (... and then Ctrl_Func_Call ...); 6245 6246 -- Similar case occurs when the node is related to an object 6247 -- declaration or assignment: 6248 6249 -- Obj [: Some_Typ] := ... and then Ctrl_Func_Call ...; 6250 6251 -- Another case to consider is when the node is part of a return 6252 -- statement: 6253 6254 -- return ... and then Ctrl_Func_Call ...; 6255 6256 -- Another case is when the node acts as a formal in a procedure 6257 -- call statement: 6258 6259 -- Proc (... and then Ctrl_Func_Call ...); 6260 6261 if Scope_Is_Transient then 6262 Wrapped_Node := Node_To_Be_Wrapped; 6263 else 6264 Wrapped_Node := Empty; 6265 end if; 6266 6267 while Present (Par) loop 6268 if Par = Wrapped_Node 6269 or else Nkind (Par) in N_Assignment_Statement 6270 | N_Object_Declaration 6271 | N_Pragma 6272 | N_Procedure_Call_Statement 6273 | N_Simple_Return_Statement 6274 then 6275 return Par; 6276 6277 -- Prevent the search from going too far 6278 6279 elsif Is_Body_Or_Package_Declaration (Par) then 6280 exit; 6281 end if; 6282 6283 Par := Parent (Par); 6284 end loop; 6285 6286 -- Return the topmost short circuit operator 6287 6288 return Top; 6289 end if; 6290 end Find_Hook_Context; 6291 6292 ------------------------------ 6293 -- Following_Address_Clause -- 6294 ------------------------------ 6295 6296 function Following_Address_Clause (D : Node_Id) return Node_Id is 6297 Id : constant Entity_Id := Defining_Identifier (D); 6298 Result : Node_Id; 6299 Par : Node_Id; 6300 6301 function Check_Decls (D : Node_Id) return Node_Id; 6302 -- This internal function differs from the main function in that it 6303 -- gets called to deal with a following package private part, and 6304 -- it checks declarations starting with D (the main function checks 6305 -- declarations following D). If D is Empty, then Empty is returned. 6306 6307 ----------------- 6308 -- Check_Decls -- 6309 ----------------- 6310 6311 function Check_Decls (D : Node_Id) return Node_Id is 6312 Decl : Node_Id; 6313 6314 begin 6315 Decl := D; 6316 while Present (Decl) loop 6317 if Nkind (Decl) = N_At_Clause 6318 and then Chars (Identifier (Decl)) = Chars (Id) 6319 then 6320 return Decl; 6321 6322 elsif Nkind (Decl) = N_Attribute_Definition_Clause 6323 and then Chars (Decl) = Name_Address 6324 and then Chars (Name (Decl)) = Chars (Id) 6325 then 6326 return Decl; 6327 end if; 6328 6329 Next (Decl); 6330 end loop; 6331 6332 -- Otherwise not found, return Empty 6333 6334 return Empty; 6335 end Check_Decls; 6336 6337 -- Start of processing for Following_Address_Clause 6338 6339 begin 6340 -- If parser detected no address clause for the identifier in question, 6341 -- then the answer is a quick NO, without the need for a search. 6342 6343 if not Get_Name_Table_Boolean1 (Chars (Id)) then 6344 return Empty; 6345 end if; 6346 6347 -- Otherwise search current declarative unit 6348 6349 Result := Check_Decls (Next (D)); 6350 6351 if Present (Result) then 6352 return Result; 6353 end if; 6354 6355 -- Check for possible package private part following 6356 6357 Par := Parent (D); 6358 6359 if Nkind (Par) = N_Package_Specification 6360 and then Visible_Declarations (Par) = List_Containing (D) 6361 and then Present (Private_Declarations (Par)) 6362 then 6363 -- Private part present, check declarations there 6364 6365 return Check_Decls (First (Private_Declarations (Par))); 6366 6367 else 6368 -- No private part, clause not found, return Empty 6369 6370 return Empty; 6371 end if; 6372 end Following_Address_Clause; 6373 6374 ---------------------- 6375 -- Force_Evaluation -- 6376 ---------------------- 6377 6378 procedure Force_Evaluation 6379 (Exp : Node_Id; 6380 Name_Req : Boolean := False; 6381 Related_Id : Entity_Id := Empty; 6382 Is_Low_Bound : Boolean := False; 6383 Is_High_Bound : Boolean := False; 6384 Mode : Force_Evaluation_Mode := Relaxed) 6385 is 6386 begin 6387 Remove_Side_Effects 6388 (Exp => Exp, 6389 Name_Req => Name_Req, 6390 Variable_Ref => True, 6391 Renaming_Req => False, 6392 Related_Id => Related_Id, 6393 Is_Low_Bound => Is_Low_Bound, 6394 Is_High_Bound => Is_High_Bound, 6395 Check_Side_Effects => 6396 Is_Static_Expression (Exp) 6397 or else Mode = Relaxed); 6398 end Force_Evaluation; 6399 6400 --------------------------------- 6401 -- Fully_Qualified_Name_String -- 6402 --------------------------------- 6403 6404 function Fully_Qualified_Name_String 6405 (E : Entity_Id; 6406 Append_NUL : Boolean := True) return String_Id 6407 is 6408 procedure Internal_Full_Qualified_Name (E : Entity_Id); 6409 -- Compute recursively the qualified name without NUL at the end, adding 6410 -- it to the currently started string being generated 6411 6412 ---------------------------------- 6413 -- Internal_Full_Qualified_Name -- 6414 ---------------------------------- 6415 6416 procedure Internal_Full_Qualified_Name (E : Entity_Id) is 6417 Ent : Entity_Id; 6418 6419 begin 6420 -- Deal properly with child units 6421 6422 if Nkind (E) = N_Defining_Program_Unit_Name then 6423 Ent := Defining_Identifier (E); 6424 else 6425 Ent := E; 6426 end if; 6427 6428 -- Compute qualification recursively (only "Standard" has no scope) 6429 6430 if Present (Scope (Scope (Ent))) then 6431 Internal_Full_Qualified_Name (Scope (Ent)); 6432 Store_String_Char (Get_Char_Code ('.')); 6433 end if; 6434 6435 -- Every entity should have a name except some expanded blocks 6436 -- don't bother about those. 6437 6438 if Chars (Ent) = No_Name then 6439 return; 6440 end if; 6441 6442 -- Generates the entity name in upper case 6443 6444 Get_Decoded_Name_String (Chars (Ent)); 6445 Set_All_Upper_Case; 6446 Store_String_Chars (Name_Buffer (1 .. Name_Len)); 6447 return; 6448 end Internal_Full_Qualified_Name; 6449 6450 -- Start of processing for Full_Qualified_Name 6451 6452 begin 6453 Start_String; 6454 Internal_Full_Qualified_Name (E); 6455 6456 if Append_NUL then 6457 Store_String_Char (Get_Char_Code (ASCII.NUL)); 6458 end if; 6459 6460 return End_String; 6461 end Fully_Qualified_Name_String; 6462 6463 --------------------------------- 6464 -- Get_Current_Value_Condition -- 6465 --------------------------------- 6466 6467 -- Note: the implementation of this procedure is very closely tied to the 6468 -- implementation of Set_Current_Value_Condition. In the Get procedure, we 6469 -- interpret Current_Value fields set by the Set procedure, so the two 6470 -- procedures need to be closely coordinated. 6471 6472 procedure Get_Current_Value_Condition 6473 (Var : Node_Id; 6474 Op : out Node_Kind; 6475 Val : out Node_Id) 6476 is 6477 Loc : constant Source_Ptr := Sloc (Var); 6478 Ent : constant Entity_Id := Entity (Var); 6479 6480 procedure Process_Current_Value_Condition (N : Node_Id; S : Boolean); 6481 -- N is an expression which holds either True (S = True) or False (S = 6482 -- False) in the condition. This procedure digs out the expression and 6483 -- if it refers to Ent, sets Op and Val appropriately. 6484 6485 ------------------------------------- 6486 -- Process_Current_Value_Condition -- 6487 ------------------------------------- 6488 6489 procedure Process_Current_Value_Condition 6490 (N : Node_Id; 6491 S : Boolean) 6492 is 6493 Cond : Node_Id; 6494 Prev_Cond : Node_Id; 6495 Sens : Boolean; 6496 6497 begin 6498 Cond := N; 6499 Sens := S; 6500 6501 loop 6502 Prev_Cond := Cond; 6503 6504 -- Deal with NOT operators, inverting sense 6505 6506 while Nkind (Cond) = N_Op_Not loop 6507 Cond := Right_Opnd (Cond); 6508 Sens := not Sens; 6509 end loop; 6510 6511 -- Deal with conversions, qualifications, and expressions with 6512 -- actions. 6513 6514 while Nkind (Cond) in N_Type_Conversion 6515 | N_Qualified_Expression 6516 | N_Expression_With_Actions 6517 loop 6518 Cond := Expression (Cond); 6519 end loop; 6520 6521 exit when Cond = Prev_Cond; 6522 end loop; 6523 6524 -- Deal with AND THEN and AND cases 6525 6526 if Nkind (Cond) in N_And_Then | N_Op_And then 6527 6528 -- Don't ever try to invert a condition that is of the form of an 6529 -- AND or AND THEN (since we are not doing sufficiently general 6530 -- processing to allow this). 6531 6532 if Sens = False then 6533 Op := N_Empty; 6534 Val := Empty; 6535 return; 6536 end if; 6537 6538 -- Recursively process AND and AND THEN branches 6539 6540 Process_Current_Value_Condition (Left_Opnd (Cond), True); 6541 pragma Assert (Op'Valid); 6542 6543 if Op /= N_Empty then 6544 return; 6545 end if; 6546 6547 Process_Current_Value_Condition (Right_Opnd (Cond), True); 6548 return; 6549 6550 -- Case of relational operator 6551 6552 elsif Nkind (Cond) in N_Op_Compare then 6553 Op := Nkind (Cond); 6554 6555 -- Invert sense of test if inverted test 6556 6557 if Sens = False then 6558 case Op is 6559 when N_Op_Eq => Op := N_Op_Ne; 6560 when N_Op_Ne => Op := N_Op_Eq; 6561 when N_Op_Lt => Op := N_Op_Ge; 6562 when N_Op_Gt => Op := N_Op_Le; 6563 when N_Op_Le => Op := N_Op_Gt; 6564 when N_Op_Ge => Op := N_Op_Lt; 6565 when others => raise Program_Error; 6566 end case; 6567 end if; 6568 6569 -- Case of entity op value 6570 6571 if Is_Entity_Name (Left_Opnd (Cond)) 6572 and then Ent = Entity (Left_Opnd (Cond)) 6573 and then Compile_Time_Known_Value (Right_Opnd (Cond)) 6574 then 6575 Val := Right_Opnd (Cond); 6576 6577 -- Case of value op entity 6578 6579 elsif Is_Entity_Name (Right_Opnd (Cond)) 6580 and then Ent = Entity (Right_Opnd (Cond)) 6581 and then Compile_Time_Known_Value (Left_Opnd (Cond)) 6582 then 6583 Val := Left_Opnd (Cond); 6584 6585 -- We are effectively swapping operands 6586 6587 case Op is 6588 when N_Op_Eq => null; 6589 when N_Op_Ne => null; 6590 when N_Op_Lt => Op := N_Op_Gt; 6591 when N_Op_Gt => Op := N_Op_Lt; 6592 when N_Op_Le => Op := N_Op_Ge; 6593 when N_Op_Ge => Op := N_Op_Le; 6594 when others => raise Program_Error; 6595 end case; 6596 6597 else 6598 Op := N_Empty; 6599 end if; 6600 6601 return; 6602 6603 elsif Nkind (Cond) in N_Type_Conversion 6604 | N_Qualified_Expression 6605 | N_Expression_With_Actions 6606 then 6607 Cond := Expression (Cond); 6608 6609 -- Case of Boolean variable reference, return as though the 6610 -- reference had said var = True. 6611 6612 else 6613 if Is_Entity_Name (Cond) and then Ent = Entity (Cond) then 6614 Val := New_Occurrence_Of (Standard_True, Sloc (Cond)); 6615 6616 if Sens = False then 6617 Op := N_Op_Ne; 6618 else 6619 Op := N_Op_Eq; 6620 end if; 6621 end if; 6622 end if; 6623 end Process_Current_Value_Condition; 6624 6625 -- Start of processing for Get_Current_Value_Condition 6626 6627 begin 6628 Op := N_Empty; 6629 Val := Empty; 6630 6631 -- Immediate return, nothing doing, if this is not an object 6632 6633 if not Is_Object (Ent) then 6634 return; 6635 end if; 6636 6637 -- In GNATprove mode we don't want to use current value optimizer, in 6638 -- particular for loop invariant expressions and other assertions that 6639 -- act as cut points for proof. The optimizer often folds expressions 6640 -- into True/False where they trivially follow from the previous 6641 -- assignments, but this deprives proof from the information needed to 6642 -- discharge checks that are beyond the scope of the value optimizer. 6643 6644 if GNATprove_Mode then 6645 return; 6646 end if; 6647 6648 -- Otherwise examine current value 6649 6650 declare 6651 CV : constant Node_Id := Current_Value (Ent); 6652 Sens : Boolean; 6653 Stm : Node_Id; 6654 6655 begin 6656 -- If statement. Condition is known true in THEN section, known False 6657 -- in any ELSIF or ELSE part, and unknown outside the IF statement. 6658 6659 if Nkind (CV) = N_If_Statement then 6660 6661 -- Before start of IF statement 6662 6663 if Loc < Sloc (CV) then 6664 return; 6665 6666 -- After end of IF statement 6667 6668 elsif Loc >= Sloc (CV) + Text_Ptr (UI_To_Int (End_Span (CV))) then 6669 return; 6670 end if; 6671 6672 -- At this stage we know that we are within the IF statement, but 6673 -- unfortunately, the tree does not record the SLOC of the ELSE so 6674 -- we cannot use a simple SLOC comparison to distinguish between 6675 -- the then/else statements, so we have to climb the tree. 6676 6677 declare 6678 N : Node_Id; 6679 6680 begin 6681 N := Parent (Var); 6682 while Parent (N) /= CV loop 6683 N := Parent (N); 6684 6685 -- If we fall off the top of the tree, then that's odd, but 6686 -- perhaps it could occur in some error situation, and the 6687 -- safest response is simply to assume that the outcome of 6688 -- the condition is unknown. No point in bombing during an 6689 -- attempt to optimize things. 6690 6691 if No (N) then 6692 return; 6693 end if; 6694 end loop; 6695 6696 -- Now we have N pointing to a node whose parent is the IF 6697 -- statement in question, so now we can tell if we are within 6698 -- the THEN statements. 6699 6700 if Is_List_Member (N) 6701 and then List_Containing (N) = Then_Statements (CV) 6702 then 6703 Sens := True; 6704 6705 -- If the variable reference does not come from source, we 6706 -- cannot reliably tell whether it appears in the else part. 6707 -- In particular, if it appears in generated code for a node 6708 -- that requires finalization, it may be attached to a list 6709 -- that has not been yet inserted into the code. For now, 6710 -- treat it as unknown. 6711 6712 elsif not Comes_From_Source (N) then 6713 return; 6714 6715 -- Otherwise we must be in ELSIF or ELSE part 6716 6717 else 6718 Sens := False; 6719 end if; 6720 end; 6721 6722 -- ELSIF part. Condition is known true within the referenced 6723 -- ELSIF, known False in any subsequent ELSIF or ELSE part, 6724 -- and unknown before the ELSE part or after the IF statement. 6725 6726 elsif Nkind (CV) = N_Elsif_Part then 6727 6728 -- if the Elsif_Part had condition_actions, the elsif has been 6729 -- rewritten as a nested if, and the original elsif_part is 6730 -- detached from the tree, so there is no way to obtain useful 6731 -- information on the current value of the variable. 6732 -- Can this be improved ??? 6733 6734 if No (Parent (CV)) then 6735 return; 6736 end if; 6737 6738 Stm := Parent (CV); 6739 6740 -- If the tree has been otherwise rewritten there is nothing 6741 -- else to be done either. 6742 6743 if Nkind (Stm) /= N_If_Statement then 6744 return; 6745 end if; 6746 6747 -- Before start of ELSIF part 6748 6749 if Loc < Sloc (CV) then 6750 return; 6751 6752 -- After end of IF statement 6753 6754 elsif Loc >= Sloc (Stm) + 6755 Text_Ptr (UI_To_Int (End_Span (Stm))) 6756 then 6757 return; 6758 end if; 6759 6760 -- Again we lack the SLOC of the ELSE, so we need to climb the 6761 -- tree to see if we are within the ELSIF part in question. 6762 6763 declare 6764 N : Node_Id; 6765 6766 begin 6767 N := Parent (Var); 6768 while Parent (N) /= Stm loop 6769 N := Parent (N); 6770 6771 -- If we fall off the top of the tree, then that's odd, but 6772 -- perhaps it could occur in some error situation, and the 6773 -- safest response is simply to assume that the outcome of 6774 -- the condition is unknown. No point in bombing during an 6775 -- attempt to optimize things. 6776 6777 if No (N) then 6778 return; 6779 end if; 6780 end loop; 6781 6782 -- Now we have N pointing to a node whose parent is the IF 6783 -- statement in question, so see if is the ELSIF part we want. 6784 -- the THEN statements. 6785 6786 if N = CV then 6787 Sens := True; 6788 6789 -- Otherwise we must be in subsequent ELSIF or ELSE part 6790 6791 else 6792 Sens := False; 6793 end if; 6794 end; 6795 6796 -- Iteration scheme of while loop. The condition is known to be 6797 -- true within the body of the loop. 6798 6799 elsif Nkind (CV) = N_Iteration_Scheme then 6800 declare 6801 Loop_Stmt : constant Node_Id := Parent (CV); 6802 6803 begin 6804 -- Before start of body of loop 6805 6806 if Loc < Sloc (Loop_Stmt) then 6807 return; 6808 6809 -- After end of LOOP statement 6810 6811 elsif Loc >= Sloc (End_Label (Loop_Stmt)) then 6812 return; 6813 6814 -- We are within the body of the loop 6815 6816 else 6817 Sens := True; 6818 end if; 6819 end; 6820 6821 -- All other cases of Current_Value settings 6822 6823 else 6824 return; 6825 end if; 6826 6827 -- If we fall through here, then we have a reportable condition, Sens 6828 -- is True if the condition is true and False if it needs inverting. 6829 6830 Process_Current_Value_Condition (Condition (CV), Sens); 6831 end; 6832 end Get_Current_Value_Condition; 6833 6834 ----------------------- 6835 -- Get_Index_Subtype -- 6836 ----------------------- 6837 6838 function Get_Index_Subtype (N : Node_Id) return Node_Id is 6839 P_Type : Entity_Id := Etype (Prefix (N)); 6840 Indx : Node_Id; 6841 J : Int; 6842 6843 begin 6844 if Is_Access_Type (P_Type) then 6845 P_Type := Designated_Type (P_Type); 6846 end if; 6847 6848 if No (Expressions (N)) then 6849 J := 1; 6850 else 6851 J := UI_To_Int (Expr_Value (First (Expressions (N)))); 6852 end if; 6853 6854 Indx := First_Index (P_Type); 6855 while J > 1 loop 6856 Next_Index (Indx); 6857 J := J - 1; 6858 end loop; 6859 6860 return Etype (Indx); 6861 end Get_Index_Subtype; 6862 6863 --------------------- 6864 -- Get_Stream_Size -- 6865 --------------------- 6866 6867 function Get_Stream_Size (E : Entity_Id) return Uint is 6868 begin 6869 -- If we have a Stream_Size clause for this type use it 6870 6871 if Has_Stream_Size_Clause (E) then 6872 return Static_Integer (Expression (Stream_Size_Clause (E))); 6873 6874 -- Otherwise the Stream_Size is the size of the type 6875 6876 else 6877 return Esize (E); 6878 end if; 6879 end Get_Stream_Size; 6880 6881 --------------------------- 6882 -- Has_Access_Constraint -- 6883 --------------------------- 6884 6885 function Has_Access_Constraint (E : Entity_Id) return Boolean is 6886 Disc : Entity_Id; 6887 T : constant Entity_Id := Etype (E); 6888 6889 begin 6890 if Has_Per_Object_Constraint (E) and then Has_Discriminants (T) then 6891 Disc := First_Discriminant (T); 6892 while Present (Disc) loop 6893 if Is_Access_Type (Etype (Disc)) then 6894 return True; 6895 end if; 6896 6897 Next_Discriminant (Disc); 6898 end loop; 6899 6900 return False; 6901 else 6902 return False; 6903 end if; 6904 end Has_Access_Constraint; 6905 6906 -------------------- 6907 -- Homonym_Number -- 6908 -------------------- 6909 6910 function Homonym_Number (Subp : Entity_Id) return Pos is 6911 Hom : Entity_Id := Homonym (Subp); 6912 Count : Pos := 1; 6913 6914 begin 6915 while Present (Hom) loop 6916 if Scope (Hom) = Scope (Subp) then 6917 Count := Count + 1; 6918 end if; 6919 6920 Hom := Homonym (Hom); 6921 end loop; 6922 6923 return Count; 6924 end Homonym_Number; 6925 6926 ----------------------------------- 6927 -- In_Library_Level_Package_Body -- 6928 ----------------------------------- 6929 6930 function In_Library_Level_Package_Body (Id : Entity_Id) return Boolean is 6931 begin 6932 -- First determine whether the entity appears at the library level, then 6933 -- look at the containing unit. 6934 6935 if Is_Library_Level_Entity (Id) then 6936 declare 6937 Container : constant Node_Id := Cunit (Get_Source_Unit (Id)); 6938 6939 begin 6940 return Nkind (Unit (Container)) = N_Package_Body; 6941 end; 6942 end if; 6943 6944 return False; 6945 end In_Library_Level_Package_Body; 6946 6947 ------------------------------ 6948 -- In_Unconditional_Context -- 6949 ------------------------------ 6950 6951 function In_Unconditional_Context (Node : Node_Id) return Boolean is 6952 P : Node_Id; 6953 6954 begin 6955 P := Node; 6956 while Present (P) loop 6957 case Nkind (P) is 6958 when N_Subprogram_Body => return True; 6959 when N_If_Statement => return False; 6960 when N_Loop_Statement => return False; 6961 when N_Case_Statement => return False; 6962 when others => P := Parent (P); 6963 end case; 6964 end loop; 6965 6966 return False; 6967 end In_Unconditional_Context; 6968 6969 ------------------- 6970 -- Insert_Action -- 6971 ------------------- 6972 6973 procedure Insert_Action 6974 (Assoc_Node : Node_Id; 6975 Ins_Action : Node_Id; 6976 Spec_Expr_OK : Boolean := False) 6977 is 6978 begin 6979 if Present (Ins_Action) then 6980 Insert_Actions 6981 (Assoc_Node => Assoc_Node, 6982 Ins_Actions => New_List (Ins_Action), 6983 Spec_Expr_OK => Spec_Expr_OK); 6984 end if; 6985 end Insert_Action; 6986 6987 -- Version with check(s) suppressed 6988 6989 procedure Insert_Action 6990 (Assoc_Node : Node_Id; 6991 Ins_Action : Node_Id; 6992 Suppress : Check_Id; 6993 Spec_Expr_OK : Boolean := False) 6994 is 6995 begin 6996 Insert_Actions 6997 (Assoc_Node => Assoc_Node, 6998 Ins_Actions => New_List (Ins_Action), 6999 Suppress => Suppress, 7000 Spec_Expr_OK => Spec_Expr_OK); 7001 end Insert_Action; 7002 7003 ------------------------- 7004 -- Insert_Action_After -- 7005 ------------------------- 7006 7007 procedure Insert_Action_After 7008 (Assoc_Node : Node_Id; 7009 Ins_Action : Node_Id) 7010 is 7011 begin 7012 Insert_Actions_After (Assoc_Node, New_List (Ins_Action)); 7013 end Insert_Action_After; 7014 7015 -------------------- 7016 -- Insert_Actions -- 7017 -------------------- 7018 7019 procedure Insert_Actions 7020 (Assoc_Node : Node_Id; 7021 Ins_Actions : List_Id; 7022 Spec_Expr_OK : Boolean := False) 7023 is 7024 N : Node_Id; 7025 P : Node_Id; 7026 7027 Wrapped_Node : Node_Id := Empty; 7028 7029 begin 7030 if No (Ins_Actions) or else Is_Empty_List (Ins_Actions) then 7031 return; 7032 end if; 7033 7034 -- Insert the action when the context is "Handling of Default and Per- 7035 -- Object Expressions" only when requested by the caller. 7036 7037 if Spec_Expr_OK then 7038 null; 7039 7040 -- Ignore insert of actions from inside default expression (or other 7041 -- similar "spec expression") in the special spec-expression analyze 7042 -- mode. Any insertions at this point have no relevance, since we are 7043 -- only doing the analyze to freeze the types of any static expressions. 7044 -- See section "Handling of Default and Per-Object Expressions" in the 7045 -- spec of package Sem for further details. 7046 7047 elsif In_Spec_Expression then 7048 return; 7049 end if; 7050 7051 -- If the action derives from stuff inside a record, then the actions 7052 -- are attached to the current scope, to be inserted and analyzed on 7053 -- exit from the scope. The reason for this is that we may also be 7054 -- generating freeze actions at the same time, and they must eventually 7055 -- be elaborated in the correct order. 7056 7057 if Is_Record_Type (Current_Scope) 7058 and then not Is_Frozen (Current_Scope) 7059 then 7060 if No (Scope_Stack.Table 7061 (Scope_Stack.Last).Pending_Freeze_Actions) 7062 then 7063 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions := 7064 Ins_Actions; 7065 else 7066 Append_List 7067 (Ins_Actions, 7068 Scope_Stack.Table (Scope_Stack.Last).Pending_Freeze_Actions); 7069 end if; 7070 7071 return; 7072 end if; 7073 7074 -- We now intend to climb up the tree to find the right point to 7075 -- insert the actions. We start at Assoc_Node, unless this node is a 7076 -- subexpression in which case we start with its parent. We do this for 7077 -- two reasons. First it speeds things up. Second, if Assoc_Node is 7078 -- itself one of the special nodes like N_And_Then, then we assume that 7079 -- an initial request to insert actions for such a node does not expect 7080 -- the actions to get deposited in the node for later handling when the 7081 -- node is expanded, since clearly the node is being dealt with by the 7082 -- caller. Note that in the subexpression case, N is always the child we 7083 -- came from. 7084 7085 -- N_Raise_xxx_Error is an annoying special case, it is a statement 7086 -- if it has type Standard_Void_Type, and a subexpression otherwise. 7087 -- Procedure calls, and similarly procedure attribute references, are 7088 -- also statements. 7089 7090 if Nkind (Assoc_Node) in N_Subexpr 7091 and then (Nkind (Assoc_Node) not in N_Raise_xxx_Error 7092 or else Etype (Assoc_Node) /= Standard_Void_Type) 7093 and then Nkind (Assoc_Node) /= N_Procedure_Call_Statement 7094 and then (Nkind (Assoc_Node) /= N_Attribute_Reference 7095 or else not Is_Procedure_Attribute_Name 7096 (Attribute_Name (Assoc_Node))) 7097 then 7098 N := Assoc_Node; 7099 P := Parent (Assoc_Node); 7100 7101 -- Nonsubexpression case. Note that N is initially Empty in this case 7102 -- (N is only guaranteed non-Empty in the subexpr case). 7103 7104 else 7105 N := Empty; 7106 P := Assoc_Node; 7107 end if; 7108 7109 -- Capture root of the transient scope 7110 7111 if Scope_Is_Transient then 7112 Wrapped_Node := Node_To_Be_Wrapped; 7113 end if; 7114 7115 loop 7116 pragma Assert (Present (P)); 7117 7118 -- Make sure that inserted actions stay in the transient scope 7119 7120 if Present (Wrapped_Node) and then N = Wrapped_Node then 7121 Store_Before_Actions_In_Scope (Ins_Actions); 7122 return; 7123 end if; 7124 7125 case Nkind (P) is 7126 7127 -- Case of right operand of AND THEN or OR ELSE. Put the actions 7128 -- in the Actions field of the right operand. They will be moved 7129 -- out further when the AND THEN or OR ELSE operator is expanded. 7130 -- Nothing special needs to be done for the left operand since 7131 -- in that case the actions are executed unconditionally. 7132 7133 when N_Short_Circuit => 7134 if N = Right_Opnd (P) then 7135 7136 -- We are now going to either append the actions to the 7137 -- actions field of the short-circuit operation. We will 7138 -- also analyze the actions now. 7139 7140 -- This analysis is really too early, the proper thing would 7141 -- be to just park them there now, and only analyze them if 7142 -- we find we really need them, and to it at the proper 7143 -- final insertion point. However attempting to this proved 7144 -- tricky, so for now we just kill current values before and 7145 -- after the analyze call to make sure we avoid peculiar 7146 -- optimizations from this out of order insertion. 7147 7148 Kill_Current_Values; 7149 7150 -- If P has already been expanded, we can't park new actions 7151 -- on it, so we need to expand them immediately, introducing 7152 -- an Expression_With_Actions. N can't be an expression 7153 -- with actions, or else then the actions would have been 7154 -- inserted at an inner level. 7155 7156 if Analyzed (P) then 7157 pragma Assert (Nkind (N) /= N_Expression_With_Actions); 7158 Rewrite (N, 7159 Make_Expression_With_Actions (Sloc (N), 7160 Actions => Ins_Actions, 7161 Expression => Relocate_Node (N))); 7162 Analyze_And_Resolve (N); 7163 7164 elsif Present (Actions (P)) then 7165 Insert_List_After_And_Analyze 7166 (Last (Actions (P)), Ins_Actions); 7167 else 7168 Set_Actions (P, Ins_Actions); 7169 Analyze_List (Actions (P)); 7170 end if; 7171 7172 Kill_Current_Values; 7173 7174 return; 7175 end if; 7176 7177 -- Then or Else dependent expression of an if expression. Add 7178 -- actions to Then_Actions or Else_Actions field as appropriate. 7179 -- The actions will be moved further out when the if is expanded. 7180 7181 when N_If_Expression => 7182 declare 7183 ThenX : constant Node_Id := Next (First (Expressions (P))); 7184 ElseX : constant Node_Id := Next (ThenX); 7185 7186 begin 7187 -- If the enclosing expression is already analyzed, as 7188 -- is the case for nested elaboration checks, insert the 7189 -- conditional further out. 7190 7191 if Analyzed (P) then 7192 null; 7193 7194 -- Actions belong to the then expression, temporarily place 7195 -- them as Then_Actions of the if expression. They will be 7196 -- moved to the proper place later when the if expression 7197 -- is expanded. 7198 7199 elsif N = ThenX then 7200 if Present (Then_Actions (P)) then 7201 Insert_List_After_And_Analyze 7202 (Last (Then_Actions (P)), Ins_Actions); 7203 else 7204 Set_Then_Actions (P, Ins_Actions); 7205 Analyze_List (Then_Actions (P)); 7206 end if; 7207 7208 return; 7209 7210 -- Actions belong to the else expression, temporarily place 7211 -- them as Else_Actions of the if expression. They will be 7212 -- moved to the proper place later when the if expression 7213 -- is expanded. 7214 7215 elsif N = ElseX then 7216 if Present (Else_Actions (P)) then 7217 Insert_List_After_And_Analyze 7218 (Last (Else_Actions (P)), Ins_Actions); 7219 else 7220 Set_Else_Actions (P, Ins_Actions); 7221 Analyze_List (Else_Actions (P)); 7222 end if; 7223 7224 return; 7225 7226 -- Actions belong to the condition. In this case they are 7227 -- unconditionally executed, and so we can continue the 7228 -- search for the proper insert point. 7229 7230 else 7231 null; 7232 end if; 7233 end; 7234 7235 -- Alternative of case expression, we place the action in the 7236 -- Actions field of the case expression alternative, this will 7237 -- be handled when the case expression is expanded. 7238 7239 when N_Case_Expression_Alternative => 7240 if Present (Actions (P)) then 7241 Insert_List_After_And_Analyze 7242 (Last (Actions (P)), Ins_Actions); 7243 else 7244 Set_Actions (P, Ins_Actions); 7245 Analyze_List (Actions (P)); 7246 end if; 7247 7248 return; 7249 7250 -- Case of appearing within an Expressions_With_Actions node. When 7251 -- the new actions come from the expression of the expression with 7252 -- actions, they must be added to the existing actions. The other 7253 -- alternative is when the new actions are related to one of the 7254 -- existing actions of the expression with actions, and should 7255 -- never reach here: if actions are inserted on a statement 7256 -- within the Actions of an expression with actions, or on some 7257 -- subexpression of such a statement, then the outermost proper 7258 -- insertion point is right before the statement, and we should 7259 -- never climb up as far as the N_Expression_With_Actions itself. 7260 7261 when N_Expression_With_Actions => 7262 if N = Expression (P) then 7263 if Is_Empty_List (Actions (P)) then 7264 Append_List_To (Actions (P), Ins_Actions); 7265 Analyze_List (Actions (P)); 7266 else 7267 Insert_List_After_And_Analyze 7268 (Last (Actions (P)), Ins_Actions); 7269 end if; 7270 7271 return; 7272 7273 else 7274 raise Program_Error; 7275 end if; 7276 7277 -- Case of appearing in the condition of a while expression or 7278 -- elsif. We insert the actions into the Condition_Actions field. 7279 -- They will be moved further out when the while loop or elsif 7280 -- is analyzed. 7281 7282 when N_Elsif_Part 7283 | N_Iteration_Scheme 7284 => 7285 if N = Condition (P) then 7286 if Present (Condition_Actions (P)) then 7287 Insert_List_After_And_Analyze 7288 (Last (Condition_Actions (P)), Ins_Actions); 7289 else 7290 Set_Condition_Actions (P, Ins_Actions); 7291 7292 -- Set the parent of the insert actions explicitly. This 7293 -- is not a syntactic field, but we need the parent field 7294 -- set, in particular so that freeze can understand that 7295 -- it is dealing with condition actions, and properly 7296 -- insert the freezing actions. 7297 7298 Set_Parent (Ins_Actions, P); 7299 Analyze_List (Condition_Actions (P)); 7300 end if; 7301 7302 return; 7303 end if; 7304 7305 -- Statements, declarations, pragmas, representation clauses 7306 7307 when 7308 -- Statements 7309 7310 N_Procedure_Call_Statement 7311 | N_Statement_Other_Than_Procedure_Call 7312 7313 -- Pragmas 7314 7315 | N_Pragma 7316 7317 -- Representation_Clause 7318 7319 | N_At_Clause 7320 | N_Attribute_Definition_Clause 7321 | N_Enumeration_Representation_Clause 7322 | N_Record_Representation_Clause 7323 7324 -- Declarations 7325 7326 | N_Abstract_Subprogram_Declaration 7327 | N_Entry_Body 7328 | N_Exception_Declaration 7329 | N_Exception_Renaming_Declaration 7330 | N_Expression_Function 7331 | N_Formal_Abstract_Subprogram_Declaration 7332 | N_Formal_Concrete_Subprogram_Declaration 7333 | N_Formal_Object_Declaration 7334 | N_Formal_Type_Declaration 7335 | N_Full_Type_Declaration 7336 | N_Function_Instantiation 7337 | N_Generic_Function_Renaming_Declaration 7338 | N_Generic_Package_Declaration 7339 | N_Generic_Package_Renaming_Declaration 7340 | N_Generic_Procedure_Renaming_Declaration 7341 | N_Generic_Subprogram_Declaration 7342 | N_Implicit_Label_Declaration 7343 | N_Incomplete_Type_Declaration 7344 | N_Number_Declaration 7345 | N_Object_Declaration 7346 | N_Object_Renaming_Declaration 7347 | N_Package_Body 7348 | N_Package_Body_Stub 7349 | N_Package_Declaration 7350 | N_Package_Instantiation 7351 | N_Package_Renaming_Declaration 7352 | N_Private_Extension_Declaration 7353 | N_Private_Type_Declaration 7354 | N_Procedure_Instantiation 7355 | N_Protected_Body 7356 | N_Protected_Body_Stub 7357 | N_Single_Task_Declaration 7358 | N_Subprogram_Body 7359 | N_Subprogram_Body_Stub 7360 | N_Subprogram_Declaration 7361 | N_Subprogram_Renaming_Declaration 7362 | N_Subtype_Declaration 7363 | N_Task_Body 7364 | N_Task_Body_Stub 7365 7366 -- Use clauses can appear in lists of declarations 7367 7368 | N_Use_Package_Clause 7369 | N_Use_Type_Clause 7370 7371 -- Freeze entity behaves like a declaration or statement 7372 7373 | N_Freeze_Entity 7374 | N_Freeze_Generic_Entity 7375 => 7376 -- Do not insert here if the item is not a list member (this 7377 -- happens for example with a triggering statement, and the 7378 -- proper approach is to insert before the entire select). 7379 7380 if not Is_List_Member (P) then 7381 null; 7382 7383 -- Do not insert if parent of P is an N_Component_Association 7384 -- node (i.e. we are in the context of an N_Aggregate or 7385 -- N_Extension_Aggregate node. In this case we want to insert 7386 -- before the entire aggregate. 7387 7388 elsif Nkind (Parent (P)) = N_Component_Association then 7389 null; 7390 7391 -- Do not insert if the parent of P is either an N_Variant node 7392 -- or an N_Record_Definition node, meaning in either case that 7393 -- P is a member of a component list, and that therefore the 7394 -- actions should be inserted outside the complete record 7395 -- declaration. 7396 7397 elsif Nkind (Parent (P)) in N_Variant | N_Record_Definition then 7398 null; 7399 7400 -- Do not insert freeze nodes within the loop generated for 7401 -- an aggregate, because they may be elaborated too late for 7402 -- subsequent use in the back end: within a package spec the 7403 -- loop is part of the elaboration procedure and is only 7404 -- elaborated during the second pass. 7405 7406 -- If the loop comes from source, or the entity is local to the 7407 -- loop itself it must remain within. 7408 7409 elsif Nkind (Parent (P)) = N_Loop_Statement 7410 and then not Comes_From_Source (Parent (P)) 7411 and then Nkind (First (Ins_Actions)) = N_Freeze_Entity 7412 and then 7413 Scope (Entity (First (Ins_Actions))) /= Current_Scope 7414 then 7415 null; 7416 7417 -- Otherwise we can go ahead and do the insertion 7418 7419 elsif P = Wrapped_Node then 7420 Store_Before_Actions_In_Scope (Ins_Actions); 7421 return; 7422 7423 else 7424 Insert_List_Before_And_Analyze (P, Ins_Actions); 7425 return; 7426 end if; 7427 7428 -- the expansion of Task and protected type declarations can 7429 -- create declarations for temporaries which, like other actions 7430 -- are inserted and analyzed before the current declaraation. 7431 -- However, the current scope is the synchronized type, and 7432 -- for unnesting it is critical that the proper scope for these 7433 -- generated entities be the enclosing one. 7434 7435 when N_Task_Type_Declaration 7436 | N_Protected_Type_Declaration => 7437 7438 Push_Scope (Scope (Current_Scope)); 7439 Insert_List_Before_And_Analyze (P, Ins_Actions); 7440 Pop_Scope; 7441 return; 7442 7443 -- A special case, N_Raise_xxx_Error can act either as a statement 7444 -- or a subexpression. We tell the difference by looking at the 7445 -- Etype. It is set to Standard_Void_Type in the statement case. 7446 7447 when N_Raise_xxx_Error => 7448 if Etype (P) = Standard_Void_Type then 7449 if P = Wrapped_Node then 7450 Store_Before_Actions_In_Scope (Ins_Actions); 7451 else 7452 Insert_List_Before_And_Analyze (P, Ins_Actions); 7453 end if; 7454 7455 return; 7456 7457 -- In the subexpression case, keep climbing 7458 7459 else 7460 null; 7461 end if; 7462 7463 -- If a component association appears within a loop created for 7464 -- an array aggregate, attach the actions to the association so 7465 -- they can be subsequently inserted within the loop. For other 7466 -- component associations insert outside of the aggregate. For 7467 -- an association that will generate a loop, its Loop_Actions 7468 -- attribute is already initialized (see exp_aggr.adb). 7469 7470 -- The list of Loop_Actions can in turn generate additional ones, 7471 -- that are inserted before the associated node. If the associated 7472 -- node is outside the aggregate, the new actions are collected 7473 -- at the end of the Loop_Actions, to respect the order in which 7474 -- they are to be elaborated. 7475 7476 when N_Component_Association 7477 | N_Iterated_Component_Association 7478 | N_Iterated_Element_Association 7479 => 7480 if Nkind (Parent (P)) = N_Aggregate 7481 and then Present (Loop_Actions (P)) 7482 then 7483 if Is_Empty_List (Loop_Actions (P)) then 7484 Set_Loop_Actions (P, Ins_Actions); 7485 Analyze_List (Ins_Actions); 7486 else 7487 declare 7488 Decl : Node_Id; 7489 7490 begin 7491 -- Check whether these actions were generated by a 7492 -- declaration that is part of the Loop_Actions for 7493 -- the component_association. 7494 7495 Decl := Assoc_Node; 7496 while Present (Decl) loop 7497 exit when Parent (Decl) = P 7498 and then Is_List_Member (Decl) 7499 and then 7500 List_Containing (Decl) = Loop_Actions (P); 7501 Decl := Parent (Decl); 7502 end loop; 7503 7504 if Present (Decl) then 7505 Insert_List_Before_And_Analyze 7506 (Decl, Ins_Actions); 7507 else 7508 Insert_List_After_And_Analyze 7509 (Last (Loop_Actions (P)), Ins_Actions); 7510 end if; 7511 end; 7512 end if; 7513 7514 return; 7515 7516 else 7517 null; 7518 end if; 7519 7520 -- Special case: an attribute denoting a procedure call 7521 7522 when N_Attribute_Reference => 7523 if Is_Procedure_Attribute_Name (Attribute_Name (P)) then 7524 if P = Wrapped_Node then 7525 Store_Before_Actions_In_Scope (Ins_Actions); 7526 else 7527 Insert_List_Before_And_Analyze (P, Ins_Actions); 7528 end if; 7529 7530 return; 7531 7532 -- In the subexpression case, keep climbing 7533 7534 else 7535 null; 7536 end if; 7537 7538 -- Special case: a marker 7539 7540 when N_Call_Marker 7541 | N_Variable_Reference_Marker 7542 => 7543 if Is_List_Member (P) then 7544 Insert_List_Before_And_Analyze (P, Ins_Actions); 7545 return; 7546 end if; 7547 7548 -- A contract node should not belong to the tree 7549 7550 when N_Contract => 7551 raise Program_Error; 7552 7553 -- For all other node types, keep climbing tree 7554 7555 when N_Abortable_Part 7556 | N_Accept_Alternative 7557 | N_Access_Definition 7558 | N_Access_Function_Definition 7559 | N_Access_Procedure_Definition 7560 | N_Access_To_Object_Definition 7561 | N_Aggregate 7562 | N_Allocator 7563 | N_Aspect_Specification 7564 | N_Case_Expression 7565 | N_Case_Statement_Alternative 7566 | N_Character_Literal 7567 | N_Compilation_Unit 7568 | N_Compilation_Unit_Aux 7569 | N_Component_Clause 7570 | N_Component_Declaration 7571 | N_Component_Definition 7572 | N_Component_List 7573 | N_Constrained_Array_Definition 7574 | N_Decimal_Fixed_Point_Definition 7575 | N_Defining_Character_Literal 7576 | N_Defining_Identifier 7577 | N_Defining_Operator_Symbol 7578 | N_Defining_Program_Unit_Name 7579 | N_Delay_Alternative 7580 | N_Delta_Aggregate 7581 | N_Delta_Constraint 7582 | N_Derived_Type_Definition 7583 | N_Designator 7584 | N_Digits_Constraint 7585 | N_Discriminant_Association 7586 | N_Discriminant_Specification 7587 | N_Empty 7588 | N_Entry_Body_Formal_Part 7589 | N_Entry_Call_Alternative 7590 | N_Entry_Declaration 7591 | N_Entry_Index_Specification 7592 | N_Enumeration_Type_Definition 7593 | N_Error 7594 | N_Exception_Handler 7595 | N_Expanded_Name 7596 | N_Explicit_Dereference 7597 | N_Extension_Aggregate 7598 | N_Floating_Point_Definition 7599 | N_Formal_Decimal_Fixed_Point_Definition 7600 | N_Formal_Derived_Type_Definition 7601 | N_Formal_Discrete_Type_Definition 7602 | N_Formal_Floating_Point_Definition 7603 | N_Formal_Modular_Type_Definition 7604 | N_Formal_Ordinary_Fixed_Point_Definition 7605 | N_Formal_Package_Declaration 7606 | N_Formal_Private_Type_Definition 7607 | N_Formal_Incomplete_Type_Definition 7608 | N_Formal_Signed_Integer_Type_Definition 7609 | N_Function_Call 7610 | N_Function_Specification 7611 | N_Generic_Association 7612 | N_Handled_Sequence_Of_Statements 7613 | N_Identifier 7614 | N_In 7615 | N_Index_Or_Discriminant_Constraint 7616 | N_Indexed_Component 7617 | N_Integer_Literal 7618 | N_Iterator_Specification 7619 | N_Itype_Reference 7620 | N_Label 7621 | N_Loop_Parameter_Specification 7622 | N_Mod_Clause 7623 | N_Modular_Type_Definition 7624 | N_Not_In 7625 | N_Null 7626 | N_Op_Abs 7627 | N_Op_Add 7628 | N_Op_And 7629 | N_Op_Concat 7630 | N_Op_Divide 7631 | N_Op_Eq 7632 | N_Op_Expon 7633 | N_Op_Ge 7634 | N_Op_Gt 7635 | N_Op_Le 7636 | N_Op_Lt 7637 | N_Op_Minus 7638 | N_Op_Mod 7639 | N_Op_Multiply 7640 | N_Op_Ne 7641 | N_Op_Not 7642 | N_Op_Or 7643 | N_Op_Plus 7644 | N_Op_Rem 7645 | N_Op_Rotate_Left 7646 | N_Op_Rotate_Right 7647 | N_Op_Shift_Left 7648 | N_Op_Shift_Right 7649 | N_Op_Shift_Right_Arithmetic 7650 | N_Op_Subtract 7651 | N_Op_Xor 7652 | N_Operator_Symbol 7653 | N_Ordinary_Fixed_Point_Definition 7654 | N_Others_Choice 7655 | N_Package_Specification 7656 | N_Parameter_Association 7657 | N_Parameter_Specification 7658 | N_Pop_Constraint_Error_Label 7659 | N_Pop_Program_Error_Label 7660 | N_Pop_Storage_Error_Label 7661 | N_Pragma_Argument_Association 7662 | N_Procedure_Specification 7663 | N_Protected_Definition 7664 | N_Push_Constraint_Error_Label 7665 | N_Push_Program_Error_Label 7666 | N_Push_Storage_Error_Label 7667 | N_Qualified_Expression 7668 | N_Quantified_Expression 7669 | N_Raise_Expression 7670 | N_Range 7671 | N_Range_Constraint 7672 | N_Real_Literal 7673 | N_Real_Range_Specification 7674 | N_Record_Definition 7675 | N_Reference 7676 | N_SCIL_Dispatch_Table_Tag_Init 7677 | N_SCIL_Dispatching_Call 7678 | N_SCIL_Membership_Test 7679 | N_Selected_Component 7680 | N_Signed_Integer_Type_Definition 7681 | N_Single_Protected_Declaration 7682 | N_Slice 7683 | N_String_Literal 7684 | N_Subtype_Indication 7685 | N_Subunit 7686 | N_Target_Name 7687 | N_Task_Definition 7688 | N_Terminate_Alternative 7689 | N_Triggering_Alternative 7690 | N_Type_Conversion 7691 | N_Unchecked_Expression 7692 | N_Unchecked_Type_Conversion 7693 | N_Unconstrained_Array_Definition 7694 | N_Unused_At_End 7695 | N_Unused_At_Start 7696 | N_Variant 7697 | N_Variant_Part 7698 | N_Validate_Unchecked_Conversion 7699 | N_With_Clause 7700 => 7701 null; 7702 end case; 7703 7704 -- If we fall through above tests, keep climbing tree 7705 7706 N := P; 7707 7708 if Nkind (Parent (N)) = N_Subunit then 7709 7710 -- This is the proper body corresponding to a stub. Insertion must 7711 -- be done at the point of the stub, which is in the declarative 7712 -- part of the parent unit. 7713 7714 P := Corresponding_Stub (Parent (N)); 7715 7716 else 7717 P := Parent (N); 7718 end if; 7719 end loop; 7720 end Insert_Actions; 7721 7722 -- Version with check(s) suppressed 7723 7724 procedure Insert_Actions 7725 (Assoc_Node : Node_Id; 7726 Ins_Actions : List_Id; 7727 Suppress : Check_Id; 7728 Spec_Expr_OK : Boolean := False) 7729 is 7730 begin 7731 if Suppress = All_Checks then 7732 declare 7733 Sva : constant Suppress_Array := Scope_Suppress.Suppress; 7734 begin 7735 Scope_Suppress.Suppress := (others => True); 7736 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK); 7737 Scope_Suppress.Suppress := Sva; 7738 end; 7739 7740 else 7741 declare 7742 Svg : constant Boolean := Scope_Suppress.Suppress (Suppress); 7743 begin 7744 Scope_Suppress.Suppress (Suppress) := True; 7745 Insert_Actions (Assoc_Node, Ins_Actions, Spec_Expr_OK); 7746 Scope_Suppress.Suppress (Suppress) := Svg; 7747 end; 7748 end if; 7749 end Insert_Actions; 7750 7751 -------------------------- 7752 -- Insert_Actions_After -- 7753 -------------------------- 7754 7755 procedure Insert_Actions_After 7756 (Assoc_Node : Node_Id; 7757 Ins_Actions : List_Id) 7758 is 7759 begin 7760 if Scope_Is_Transient and then Assoc_Node = Node_To_Be_Wrapped then 7761 Store_After_Actions_In_Scope (Ins_Actions); 7762 else 7763 Insert_List_After_And_Analyze (Assoc_Node, Ins_Actions); 7764 end if; 7765 end Insert_Actions_After; 7766 7767 ------------------------ 7768 -- Insert_Declaration -- 7769 ------------------------ 7770 7771 procedure Insert_Declaration (N : Node_Id; Decl : Node_Id) is 7772 P : Node_Id; 7773 7774 begin 7775 pragma Assert (Nkind (N) in N_Subexpr); 7776 7777 -- Climb until we find a procedure or a package 7778 7779 P := N; 7780 loop 7781 pragma Assert (Present (Parent (P))); 7782 P := Parent (P); 7783 7784 if Is_List_Member (P) then 7785 exit when Nkind (Parent (P)) in 7786 N_Package_Specification | N_Subprogram_Body; 7787 7788 -- Special handling for handled sequence of statements, we must 7789 -- insert in the statements not the exception handlers! 7790 7791 if Nkind (Parent (P)) = N_Handled_Sequence_Of_Statements then 7792 P := First (Statements (Parent (P))); 7793 exit; 7794 end if; 7795 end if; 7796 end loop; 7797 7798 -- Now do the insertion 7799 7800 Insert_Before (P, Decl); 7801 Analyze (Decl); 7802 end Insert_Declaration; 7803 7804 --------------------------------- 7805 -- Insert_Library_Level_Action -- 7806 --------------------------------- 7807 7808 procedure Insert_Library_Level_Action (N : Node_Id) is 7809 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit)); 7810 7811 begin 7812 Push_Scope (Cunit_Entity (Current_Sem_Unit)); 7813 -- And not Main_Unit as previously. If the main unit is a body, 7814 -- the scope needed to analyze the actions is the entity of the 7815 -- corresponding declaration. 7816 7817 if No (Actions (Aux)) then 7818 Set_Actions (Aux, New_List (N)); 7819 else 7820 Append (N, Actions (Aux)); 7821 end if; 7822 7823 Analyze (N); 7824 Pop_Scope; 7825 end Insert_Library_Level_Action; 7826 7827 ---------------------------------- 7828 -- Insert_Library_Level_Actions -- 7829 ---------------------------------- 7830 7831 procedure Insert_Library_Level_Actions (L : List_Id) is 7832 Aux : constant Node_Id := Aux_Decls_Node (Cunit (Main_Unit)); 7833 7834 begin 7835 if Is_Non_Empty_List (L) then 7836 Push_Scope (Cunit_Entity (Main_Unit)); 7837 -- ??? should this be Current_Sem_Unit instead of Main_Unit? 7838 7839 if No (Actions (Aux)) then 7840 Set_Actions (Aux, L); 7841 Analyze_List (L); 7842 else 7843 Insert_List_After_And_Analyze (Last (Actions (Aux)), L); 7844 end if; 7845 7846 Pop_Scope; 7847 end if; 7848 end Insert_Library_Level_Actions; 7849 7850 ---------------------- 7851 -- Inside_Init_Proc -- 7852 ---------------------- 7853 7854 function Inside_Init_Proc return Boolean is 7855 Proc : constant Entity_Id := Enclosing_Init_Proc; 7856 7857 begin 7858 return Proc /= Empty; 7859 end Inside_Init_Proc; 7860 7861 ---------------------- 7862 -- Integer_Type_For -- 7863 ---------------------- 7864 7865 function Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id is 7866 begin 7867 pragma Assert (S <= System_Max_Integer_Size); 7868 7869 -- This is the canonical 32-bit type 7870 7871 if S <= Standard_Integer_Size then 7872 if Uns then 7873 return Standard_Unsigned; 7874 else 7875 return Standard_Integer; 7876 end if; 7877 7878 -- This is the canonical 64-bit type 7879 7880 elsif S <= Standard_Long_Long_Integer_Size then 7881 if Uns then 7882 return Standard_Long_Long_Unsigned; 7883 else 7884 return Standard_Long_Long_Integer; 7885 end if; 7886 7887 -- This is the canonical 128-bit type 7888 7889 elsif S <= Standard_Long_Long_Long_Integer_Size then 7890 if Uns then 7891 return Standard_Long_Long_Long_Unsigned; 7892 else 7893 return Standard_Long_Long_Long_Integer; 7894 end if; 7895 7896 else 7897 raise Program_Error; 7898 end if; 7899 end Integer_Type_For; 7900 7901 -------------------------------------------------- 7902 -- Is_Displacement_Of_Object_Or_Function_Result -- 7903 -------------------------------------------------- 7904 7905 function Is_Displacement_Of_Object_Or_Function_Result 7906 (Obj_Id : Entity_Id) return Boolean 7907 is 7908 function Is_Controlled_Function_Call (N : Node_Id) return Boolean; 7909 -- Determine whether node N denotes a controlled function call 7910 7911 function Is_Controlled_Indexing (N : Node_Id) return Boolean; 7912 -- Determine whether node N denotes a generalized indexing form which 7913 -- involves a controlled result. 7914 7915 function Is_Displace_Call (N : Node_Id) return Boolean; 7916 -- Determine whether node N denotes a call to Ada.Tags.Displace 7917 7918 function Is_Source_Object (N : Node_Id) return Boolean; 7919 -- Determine whether a particular node denotes a source object 7920 7921 function Strip (N : Node_Id) return Node_Id; 7922 -- Examine arbitrary node N by stripping various indirections and return 7923 -- the "real" node. 7924 7925 --------------------------------- 7926 -- Is_Controlled_Function_Call -- 7927 --------------------------------- 7928 7929 function Is_Controlled_Function_Call (N : Node_Id) return Boolean is 7930 Expr : Node_Id; 7931 7932 begin 7933 -- When a function call appears in Object.Operation format, the 7934 -- original representation has several possible forms depending on 7935 -- the availability and form of actual parameters: 7936 7937 -- Obj.Func N_Selected_Component 7938 -- Obj.Func (Actual) N_Indexed_Component 7939 -- Obj.Func (Formal => Actual) N_Function_Call, whose Name is an 7940 -- N_Selected_Component 7941 7942 Expr := Original_Node (N); 7943 loop 7944 if Nkind (Expr) = N_Function_Call then 7945 Expr := Name (Expr); 7946 7947 -- "Obj.Func (Actual)" case 7948 7949 elsif Nkind (Expr) = N_Indexed_Component then 7950 Expr := Prefix (Expr); 7951 7952 -- "Obj.Func" or "Obj.Func (Formal => Actual) case 7953 7954 elsif Nkind (Expr) = N_Selected_Component then 7955 Expr := Selector_Name (Expr); 7956 7957 else 7958 exit; 7959 end if; 7960 end loop; 7961 7962 return 7963 Nkind (Expr) in N_Has_Entity 7964 and then Present (Entity (Expr)) 7965 and then Ekind (Entity (Expr)) = E_Function 7966 and then Needs_Finalization (Etype (Entity (Expr))); 7967 end Is_Controlled_Function_Call; 7968 7969 ---------------------------- 7970 -- Is_Controlled_Indexing -- 7971 ---------------------------- 7972 7973 function Is_Controlled_Indexing (N : Node_Id) return Boolean is 7974 Expr : constant Node_Id := Original_Node (N); 7975 7976 begin 7977 return 7978 Nkind (Expr) = N_Indexed_Component 7979 and then Present (Generalized_Indexing (Expr)) 7980 and then Needs_Finalization (Etype (Expr)); 7981 end Is_Controlled_Indexing; 7982 7983 ---------------------- 7984 -- Is_Displace_Call -- 7985 ---------------------- 7986 7987 function Is_Displace_Call (N : Node_Id) return Boolean is 7988 Call : constant Node_Id := Strip (N); 7989 7990 begin 7991 return 7992 Present (Call) 7993 and then Nkind (Call) = N_Function_Call 7994 and then Nkind (Name (Call)) in N_Has_Entity 7995 and then Is_RTE (Entity (Name (Call)), RE_Displace); 7996 end Is_Displace_Call; 7997 7998 ---------------------- 7999 -- Is_Source_Object -- 8000 ---------------------- 8001 8002 function Is_Source_Object (N : Node_Id) return Boolean is 8003 Obj : constant Node_Id := Strip (N); 8004 8005 begin 8006 return 8007 Present (Obj) 8008 and then Comes_From_Source (Obj) 8009 and then Nkind (Obj) in N_Has_Entity 8010 and then Is_Object (Entity (Obj)); 8011 end Is_Source_Object; 8012 8013 ----------- 8014 -- Strip -- 8015 ----------- 8016 8017 function Strip (N : Node_Id) return Node_Id is 8018 Result : Node_Id; 8019 8020 begin 8021 Result := N; 8022 loop 8023 if Nkind (Result) = N_Explicit_Dereference then 8024 Result := Prefix (Result); 8025 8026 elsif Nkind (Result) in 8027 N_Type_Conversion | N_Unchecked_Type_Conversion 8028 then 8029 Result := Expression (Result); 8030 8031 else 8032 exit; 8033 end if; 8034 end loop; 8035 8036 return Result; 8037 end Strip; 8038 8039 -- Local variables 8040 8041 Obj_Decl : constant Node_Id := Declaration_Node (Obj_Id); 8042 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); 8043 Orig_Decl : constant Node_Id := Original_Node (Obj_Decl); 8044 Orig_Expr : Node_Id; 8045 8046 -- Start of processing for Is_Displacement_Of_Object_Or_Function_Result 8047 8048 begin 8049 -- Case 1: 8050 8051 -- Obj : CW_Type := Function_Call (...); 8052 8053 -- is rewritten into: 8054 8055 -- Temp : ... := Function_Call (...)'reference; 8056 -- Obj : CW_Type renames (... Ada.Tags.Displace (Temp)); 8057 8058 -- where the return type of the function and the class-wide type require 8059 -- dispatch table pointer displacement. 8060 8061 -- Case 2: 8062 8063 -- Obj : CW_Type := Container (...); 8064 8065 -- is rewritten into: 8066 8067 -- Temp : ... := Function_Call (Container, ...)'reference; 8068 -- Obj : CW_Type renames (... Ada.Tags.Displace (Temp)); 8069 8070 -- where the container element type and the class-wide type require 8071 -- dispatch table pointer dispacement. 8072 8073 -- Case 3: 8074 8075 -- Obj : CW_Type := Src_Obj; 8076 8077 -- is rewritten into: 8078 8079 -- Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj)); 8080 8081 -- where the type of the source object and the class-wide type require 8082 -- dispatch table pointer displacement. 8083 8084 if Nkind (Obj_Decl) = N_Object_Renaming_Declaration 8085 and then Is_Class_Wide_Type (Obj_Typ) 8086 and then Is_Displace_Call (Renamed_Object (Obj_Id)) 8087 and then Nkind (Orig_Decl) = N_Object_Declaration 8088 and then Comes_From_Source (Orig_Decl) 8089 then 8090 Orig_Expr := Expression (Orig_Decl); 8091 8092 return 8093 Is_Controlled_Function_Call (Orig_Expr) 8094 or else Is_Controlled_Indexing (Orig_Expr) 8095 or else Is_Source_Object (Orig_Expr); 8096 end if; 8097 8098 return False; 8099 end Is_Displacement_Of_Object_Or_Function_Result; 8100 8101 ------------------------------ 8102 -- Is_Finalizable_Transient -- 8103 ------------------------------ 8104 8105 function Is_Finalizable_Transient 8106 (Decl : Node_Id; 8107 Rel_Node : Node_Id) return Boolean 8108 is 8109 Obj_Id : constant Entity_Id := Defining_Identifier (Decl); 8110 Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id)); 8111 8112 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean; 8113 -- Determine whether transient object Trans_Id is initialized either 8114 -- by a function call which returns an access type or simply renames 8115 -- another pointer. 8116 8117 function Initialized_By_Aliased_BIP_Func_Call 8118 (Trans_Id : Entity_Id) return Boolean; 8119 -- Determine whether transient object Trans_Id is initialized by a 8120 -- build-in-place function call where the BIPalloc parameter is of 8121 -- value 1 and BIPaccess is not null. This case creates an aliasing 8122 -- between the returned value and the value denoted by BIPaccess. 8123 8124 function Is_Aliased 8125 (Trans_Id : Entity_Id; 8126 First_Stmt : Node_Id) return Boolean; 8127 -- Determine whether transient object Trans_Id has been renamed or 8128 -- aliased through 'reference in the statement list starting from 8129 -- First_Stmt. 8130 8131 function Is_Allocated (Trans_Id : Entity_Id) return Boolean; 8132 -- Determine whether transient object Trans_Id is allocated on the heap 8133 8134 function Is_Iterated_Container 8135 (Trans_Id : Entity_Id; 8136 First_Stmt : Node_Id) return Boolean; 8137 -- Determine whether transient object Trans_Id denotes a container which 8138 -- is in the process of being iterated in the statement list starting 8139 -- from First_Stmt. 8140 8141 function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean; 8142 -- Return True if N is directly part of a build-in-place return 8143 -- statement. 8144 8145 --------------------------- 8146 -- Initialized_By_Access -- 8147 --------------------------- 8148 8149 function Initialized_By_Access (Trans_Id : Entity_Id) return Boolean is 8150 Expr : constant Node_Id := Expression (Parent (Trans_Id)); 8151 8152 begin 8153 return 8154 Present (Expr) 8155 and then Nkind (Expr) /= N_Reference 8156 and then Is_Access_Type (Etype (Expr)); 8157 end Initialized_By_Access; 8158 8159 ------------------------------------------ 8160 -- Initialized_By_Aliased_BIP_Func_Call -- 8161 ------------------------------------------ 8162 8163 function Initialized_By_Aliased_BIP_Func_Call 8164 (Trans_Id : Entity_Id) return Boolean 8165 is 8166 Call : Node_Id := Expression (Parent (Trans_Id)); 8167 8168 begin 8169 -- Build-in-place calls usually appear in 'reference format 8170 8171 if Nkind (Call) = N_Reference then 8172 Call := Prefix (Call); 8173 end if; 8174 8175 Call := Unqual_Conv (Call); 8176 8177 if Is_Build_In_Place_Function_Call (Call) then 8178 declare 8179 Access_Nam : Name_Id := No_Name; 8180 Access_OK : Boolean := False; 8181 Actual : Node_Id; 8182 Alloc_Nam : Name_Id := No_Name; 8183 Alloc_OK : Boolean := False; 8184 Formal : Node_Id; 8185 Func_Id : Entity_Id; 8186 Param : Node_Id; 8187 8188 begin 8189 -- Examine all parameter associations of the function call 8190 8191 Param := First (Parameter_Associations (Call)); 8192 while Present (Param) loop 8193 if Nkind (Param) = N_Parameter_Association 8194 and then Nkind (Selector_Name (Param)) = N_Identifier 8195 then 8196 Actual := Explicit_Actual_Parameter (Param); 8197 Formal := Selector_Name (Param); 8198 8199 -- Construct the names of formals BIPaccess and BIPalloc 8200 -- using the function name retrieved from an arbitrary 8201 -- formal. 8202 8203 if Access_Nam = No_Name 8204 and then Alloc_Nam = No_Name 8205 and then Present (Entity (Formal)) 8206 then 8207 Func_Id := Scope (Entity (Formal)); 8208 8209 Access_Nam := 8210 New_External_Name (Chars (Func_Id), 8211 BIP_Formal_Suffix (BIP_Object_Access)); 8212 8213 Alloc_Nam := 8214 New_External_Name (Chars (Func_Id), 8215 BIP_Formal_Suffix (BIP_Alloc_Form)); 8216 end if; 8217 8218 -- A match for BIPaccess => Temp has been found 8219 8220 if Chars (Formal) = Access_Nam 8221 and then Nkind (Actual) /= N_Null 8222 then 8223 Access_OK := True; 8224 end if; 8225 8226 -- A match for BIPalloc => 1 has been found 8227 8228 if Chars (Formal) = Alloc_Nam 8229 and then Nkind (Actual) = N_Integer_Literal 8230 and then Intval (Actual) = Uint_1 8231 then 8232 Alloc_OK := True; 8233 end if; 8234 end if; 8235 8236 Next (Param); 8237 end loop; 8238 8239 return Access_OK and Alloc_OK; 8240 end; 8241 end if; 8242 8243 return False; 8244 end Initialized_By_Aliased_BIP_Func_Call; 8245 8246 ---------------- 8247 -- Is_Aliased -- 8248 ---------------- 8249 8250 function Is_Aliased 8251 (Trans_Id : Entity_Id; 8252 First_Stmt : Node_Id) return Boolean 8253 is 8254 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id; 8255 -- Given an object renaming declaration, retrieve the entity of the 8256 -- renamed name. Return Empty if the renamed name is anything other 8257 -- than a variable or a constant. 8258 8259 ------------------------- 8260 -- Find_Renamed_Object -- 8261 ------------------------- 8262 8263 function Find_Renamed_Object (Ren_Decl : Node_Id) return Entity_Id is 8264 Ren_Obj : Node_Id := Empty; 8265 8266 function Find_Object (N : Node_Id) return Traverse_Result; 8267 -- Try to detect an object which is either a constant or a 8268 -- variable. 8269 8270 ----------------- 8271 -- Find_Object -- 8272 ----------------- 8273 8274 function Find_Object (N : Node_Id) return Traverse_Result is 8275 begin 8276 -- Stop the search once a constant or a variable has been 8277 -- detected. 8278 8279 if Nkind (N) = N_Identifier 8280 and then Present (Entity (N)) 8281 and then Ekind (Entity (N)) in E_Constant | E_Variable 8282 then 8283 Ren_Obj := Entity (N); 8284 return Abandon; 8285 end if; 8286 8287 return OK; 8288 end Find_Object; 8289 8290 procedure Search is new Traverse_Proc (Find_Object); 8291 8292 -- Local variables 8293 8294 Typ : constant Entity_Id := Etype (Defining_Identifier (Ren_Decl)); 8295 8296 -- Start of processing for Find_Renamed_Object 8297 8298 begin 8299 -- Actions related to dispatching calls may appear as renamings of 8300 -- tags. Do not process this type of renaming because it does not 8301 -- use the actual value of the object. 8302 8303 if not Is_RTE (Typ, RE_Tag_Ptr) then 8304 Search (Name (Ren_Decl)); 8305 end if; 8306 8307 return Ren_Obj; 8308 end Find_Renamed_Object; 8309 8310 -- Local variables 8311 8312 Expr : Node_Id; 8313 Ren_Obj : Entity_Id; 8314 Stmt : Node_Id; 8315 8316 -- Start of processing for Is_Aliased 8317 8318 begin 8319 -- A controlled transient object is not considered aliased when it 8320 -- appears inside an expression_with_actions node even when there are 8321 -- explicit aliases of it: 8322 8323 -- do 8324 -- Trans_Id : Ctrl_Typ ...; -- transient object 8325 -- Alias : ... := Trans_Id; -- object is aliased 8326 -- Val : constant Boolean := 8327 -- ... Alias ...; -- aliasing ends 8328 -- <finalize Trans_Id> -- object safe to finalize 8329 -- in Val end; 8330 8331 -- Expansion ensures that all aliases are encapsulated in the actions 8332 -- list and do not leak to the expression by forcing the evaluation 8333 -- of the expression. 8334 8335 if Nkind (Rel_Node) = N_Expression_With_Actions then 8336 return False; 8337 8338 -- Otherwise examine the statements after the controlled transient 8339 -- object and look for various forms of aliasing. 8340 8341 else 8342 Stmt := First_Stmt; 8343 while Present (Stmt) loop 8344 if Nkind (Stmt) = N_Object_Declaration then 8345 Expr := Expression (Stmt); 8346 8347 -- Aliasing of the form: 8348 -- Obj : ... := Trans_Id'reference; 8349 8350 if Present (Expr) 8351 and then Nkind (Expr) = N_Reference 8352 and then Nkind (Prefix (Expr)) = N_Identifier 8353 and then Entity (Prefix (Expr)) = Trans_Id 8354 then 8355 return True; 8356 end if; 8357 8358 elsif Nkind (Stmt) = N_Object_Renaming_Declaration then 8359 Ren_Obj := Find_Renamed_Object (Stmt); 8360 8361 -- Aliasing of the form: 8362 -- Obj : ... renames ... Trans_Id ...; 8363 8364 if Present (Ren_Obj) and then Ren_Obj = Trans_Id then 8365 return True; 8366 end if; 8367 end if; 8368 8369 Next (Stmt); 8370 end loop; 8371 8372 return False; 8373 end if; 8374 end Is_Aliased; 8375 8376 ------------------ 8377 -- Is_Allocated -- 8378 ------------------ 8379 8380 function Is_Allocated (Trans_Id : Entity_Id) return Boolean is 8381 Expr : constant Node_Id := Expression (Parent (Trans_Id)); 8382 begin 8383 return 8384 Is_Access_Type (Etype (Trans_Id)) 8385 and then Present (Expr) 8386 and then Nkind (Expr) = N_Allocator; 8387 end Is_Allocated; 8388 8389 --------------------------- 8390 -- Is_Iterated_Container -- 8391 --------------------------- 8392 8393 function Is_Iterated_Container 8394 (Trans_Id : Entity_Id; 8395 First_Stmt : Node_Id) return Boolean 8396 is 8397 Aspect : Node_Id; 8398 Call : Node_Id; 8399 Iter : Entity_Id; 8400 Param : Node_Id; 8401 Stmt : Node_Id; 8402 Typ : Entity_Id; 8403 8404 begin 8405 -- It is not possible to iterate over containers in non-Ada 2012 code 8406 8407 if Ada_Version < Ada_2012 then 8408 return False; 8409 end if; 8410 8411 Typ := Etype (Trans_Id); 8412 8413 -- Handle access type created for secondary stack use 8414 8415 if Is_Access_Type (Typ) then 8416 Typ := Designated_Type (Typ); 8417 end if; 8418 8419 -- Look for aspect Default_Iterator. It may be part of a type 8420 -- declaration for a container, or inherited from a base type 8421 -- or parent type. 8422 8423 Aspect := Find_Value_Of_Aspect (Typ, Aspect_Default_Iterator); 8424 8425 if Present (Aspect) then 8426 Iter := Entity (Aspect); 8427 8428 -- Examine the statements following the container object and 8429 -- look for a call to the default iterate routine where the 8430 -- first parameter is the transient. Such a call appears as: 8431 8432 -- It : Access_To_CW_Iterator := 8433 -- Iterate (Tran_Id.all, ...)'reference; 8434 8435 Stmt := First_Stmt; 8436 while Present (Stmt) loop 8437 8438 -- Detect an object declaration which is initialized by a 8439 -- secondary stack function call. 8440 8441 if Nkind (Stmt) = N_Object_Declaration 8442 and then Present (Expression (Stmt)) 8443 and then Nkind (Expression (Stmt)) = N_Reference 8444 and then Nkind (Prefix (Expression (Stmt))) = N_Function_Call 8445 then 8446 Call := Prefix (Expression (Stmt)); 8447 8448 -- The call must invoke the default iterate routine of 8449 -- the container and the transient object must appear as 8450 -- the first actual parameter. Skip any calls whose names 8451 -- are not entities. 8452 8453 if Is_Entity_Name (Name (Call)) 8454 and then Entity (Name (Call)) = Iter 8455 and then Present (Parameter_Associations (Call)) 8456 then 8457 Param := First (Parameter_Associations (Call)); 8458 8459 if Nkind (Param) = N_Explicit_Dereference 8460 and then Entity (Prefix (Param)) = Trans_Id 8461 then 8462 return True; 8463 end if; 8464 end if; 8465 end if; 8466 8467 Next (Stmt); 8468 end loop; 8469 end if; 8470 8471 return False; 8472 end Is_Iterated_Container; 8473 8474 ------------------------------------- 8475 -- Is_Part_Of_BIP_Return_Statement -- 8476 ------------------------------------- 8477 8478 function Is_Part_Of_BIP_Return_Statement (N : Node_Id) return Boolean is 8479 Subp : constant Entity_Id := Current_Subprogram; 8480 Context : Node_Id; 8481 begin 8482 -- First check if N is part of a BIP function 8483 8484 if No (Subp) 8485 or else not Is_Build_In_Place_Function (Subp) 8486 then 8487 return False; 8488 end if; 8489 8490 -- Then check whether N is a complete part of a return statement 8491 -- Should we consider other node kinds to go up the tree??? 8492 8493 Context := N; 8494 loop 8495 case Nkind (Context) is 8496 when N_Expression_With_Actions => Context := Parent (Context); 8497 when N_Simple_Return_Statement => return True; 8498 when others => return False; 8499 end case; 8500 end loop; 8501 end Is_Part_Of_BIP_Return_Statement; 8502 8503 -- Local variables 8504 8505 Desig : Entity_Id := Obj_Typ; 8506 8507 -- Start of processing for Is_Finalizable_Transient 8508 8509 begin 8510 -- Handle access types 8511 8512 if Is_Access_Type (Desig) then 8513 Desig := Available_View (Designated_Type (Desig)); 8514 end if; 8515 8516 return 8517 Ekind (Obj_Id) in E_Constant | E_Variable 8518 and then Needs_Finalization (Desig) 8519 and then Requires_Transient_Scope (Desig) 8520 and then Nkind (Rel_Node) /= N_Simple_Return_Statement 8521 and then not Is_Part_Of_BIP_Return_Statement (Rel_Node) 8522 8523 -- Do not consider a transient object that was already processed 8524 8525 and then not Is_Finalized_Transient (Obj_Id) 8526 8527 -- Do not consider renamed or 'reference-d transient objects because 8528 -- the act of renaming extends the object's lifetime. 8529 8530 and then not Is_Aliased (Obj_Id, Decl) 8531 8532 -- Do not consider transient objects allocated on the heap since 8533 -- they are attached to a finalization master. 8534 8535 and then not Is_Allocated (Obj_Id) 8536 8537 -- If the transient object is a pointer, check that it is not 8538 -- initialized by a function that returns a pointer or acts as a 8539 -- renaming of another pointer. 8540 8541 and then not 8542 (Is_Access_Type (Obj_Typ) and then Initialized_By_Access (Obj_Id)) 8543 8544 -- Do not consider transient objects which act as indirect aliases 8545 -- of build-in-place function results. 8546 8547 and then not Initialized_By_Aliased_BIP_Func_Call (Obj_Id) 8548 8549 -- Do not consider conversions of tags to class-wide types 8550 8551 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id) 8552 8553 -- Do not consider iterators because those are treated as normal 8554 -- controlled objects and are processed by the usual finalization 8555 -- machinery. This avoids the double finalization of an iterator. 8556 8557 and then not Is_Iterator (Desig) 8558 8559 -- Do not consider containers in the context of iterator loops. Such 8560 -- transient objects must exist for as long as the loop is around, 8561 -- otherwise any operation carried out by the iterator will fail. 8562 8563 and then not Is_Iterated_Container (Obj_Id, Decl); 8564 end Is_Finalizable_Transient; 8565 8566 --------------------------------- 8567 -- Is_Fully_Repped_Tagged_Type -- 8568 --------------------------------- 8569 8570 function Is_Fully_Repped_Tagged_Type (T : Entity_Id) return Boolean is 8571 U : constant Entity_Id := Underlying_Type (T); 8572 Comp : Entity_Id; 8573 8574 begin 8575 if No (U) or else not Is_Tagged_Type (U) then 8576 return False; 8577 elsif Has_Discriminants (U) then 8578 return False; 8579 elsif not Has_Specified_Layout (U) then 8580 return False; 8581 end if; 8582 8583 -- Here we have a tagged type, see if it has any component (other than 8584 -- tag and parent) with no component_clause. If so, we return False. 8585 8586 Comp := First_Component (U); 8587 while Present (Comp) loop 8588 if not Is_Tag (Comp) 8589 and then Chars (Comp) /= Name_uParent 8590 and then No (Component_Clause (Comp)) 8591 then 8592 return False; 8593 else 8594 Next_Component (Comp); 8595 end if; 8596 end loop; 8597 8598 -- All components have clauses 8599 8600 return True; 8601 end Is_Fully_Repped_Tagged_Type; 8602 8603 ---------------------------------- 8604 -- Is_Library_Level_Tagged_Type -- 8605 ---------------------------------- 8606 8607 function Is_Library_Level_Tagged_Type (Typ : Entity_Id) return Boolean is 8608 begin 8609 return Is_Tagged_Type (Typ) and then Is_Library_Level_Entity (Typ); 8610 end Is_Library_Level_Tagged_Type; 8611 8612 -------------------------- 8613 -- Is_Non_BIP_Func_Call -- 8614 -------------------------- 8615 8616 function Is_Non_BIP_Func_Call (Expr : Node_Id) return Boolean is 8617 begin 8618 -- The expected call is of the format 8619 -- 8620 -- Func_Call'reference 8621 8622 return 8623 Nkind (Expr) = N_Reference 8624 and then Nkind (Prefix (Expr)) = N_Function_Call 8625 and then not Is_Build_In_Place_Function_Call (Prefix (Expr)); 8626 end Is_Non_BIP_Func_Call; 8627 8628 ---------------------------------- 8629 -- Is_Possibly_Unaligned_Object -- 8630 ---------------------------------- 8631 8632 function Is_Possibly_Unaligned_Object (N : Node_Id) return Boolean is 8633 T : constant Entity_Id := Etype (N); 8634 8635 begin 8636 -- If renamed object, apply test to underlying object 8637 8638 if Is_Entity_Name (N) 8639 and then Is_Object (Entity (N)) 8640 and then Present (Renamed_Object (Entity (N))) 8641 then 8642 return Is_Possibly_Unaligned_Object (Renamed_Object (Entity (N))); 8643 end if; 8644 8645 -- Tagged and controlled types and aliased types are always aligned, as 8646 -- are concurrent types. 8647 8648 if Is_Aliased (T) 8649 or else Has_Controlled_Component (T) 8650 or else Is_Concurrent_Type (T) 8651 or else Is_Tagged_Type (T) 8652 or else Is_Controlled (T) 8653 then 8654 return False; 8655 end if; 8656 8657 -- If this is an element of a packed array, may be unaligned 8658 8659 if Is_Ref_To_Bit_Packed_Array (N) then 8660 return True; 8661 end if; 8662 8663 -- Case of indexed component reference: test whether prefix is unaligned 8664 8665 if Nkind (N) = N_Indexed_Component then 8666 return Is_Possibly_Unaligned_Object (Prefix (N)); 8667 8668 -- Case of selected component reference 8669 8670 elsif Nkind (N) = N_Selected_Component then 8671 declare 8672 P : constant Node_Id := Prefix (N); 8673 C : constant Entity_Id := Entity (Selector_Name (N)); 8674 M : Nat; 8675 S : Nat; 8676 8677 begin 8678 -- If component reference is for an array with nonstatic bounds, 8679 -- then it is always aligned: we can only process unaligned arrays 8680 -- with static bounds (more precisely compile time known bounds). 8681 8682 if Is_Array_Type (T) 8683 and then not Compile_Time_Known_Bounds (T) 8684 then 8685 return False; 8686 end if; 8687 8688 -- If component is aliased, it is definitely properly aligned 8689 8690 if Is_Aliased (C) then 8691 return False; 8692 end if; 8693 8694 -- If component is for a type implemented as a scalar, and the 8695 -- record is packed, and the component is other than the first 8696 -- component of the record, then the component may be unaligned. 8697 8698 if Is_Packed (Etype (P)) 8699 and then Represented_As_Scalar (Etype (C)) 8700 and then First_Entity (Scope (C)) /= C 8701 then 8702 return True; 8703 end if; 8704 8705 -- Compute maximum possible alignment for T 8706 8707 -- If alignment is known, then that settles things 8708 8709 if Known_Alignment (T) then 8710 M := UI_To_Int (Alignment (T)); 8711 8712 -- If alignment is not known, tentatively set max alignment 8713 8714 else 8715 M := Ttypes.Maximum_Alignment; 8716 8717 -- We can reduce this if the Esize is known since the default 8718 -- alignment will never be more than the smallest power of 2 8719 -- that does not exceed this Esize value. 8720 8721 if Known_Esize (T) then 8722 S := UI_To_Int (Esize (T)); 8723 8724 while (M / 2) >= S loop 8725 M := M / 2; 8726 end loop; 8727 end if; 8728 end if; 8729 8730 -- The following code is historical, it used to be present but it 8731 -- is too cautious, because the front-end does not know the proper 8732 -- default alignments for the target. Also, if the alignment is 8733 -- not known, the front end can't know in any case. If a copy is 8734 -- needed, the back-end will take care of it. This whole section 8735 -- including this comment can be removed later ??? 8736 8737 -- If the component reference is for a record that has a specified 8738 -- alignment, and we either know it is too small, or cannot tell, 8739 -- then the component may be unaligned. 8740 8741 -- What is the following commented out code ??? 8742 8743 -- if Known_Alignment (Etype (P)) 8744 -- and then Alignment (Etype (P)) < Ttypes.Maximum_Alignment 8745 -- and then M > Alignment (Etype (P)) 8746 -- then 8747 -- return True; 8748 -- end if; 8749 8750 -- Case of component clause present which may specify an 8751 -- unaligned position. 8752 8753 if Present (Component_Clause (C)) then 8754 8755 -- Otherwise we can do a test to make sure that the actual 8756 -- start position in the record, and the length, are both 8757 -- consistent with the required alignment. If not, we know 8758 -- that we are unaligned. 8759 8760 declare 8761 Align_In_Bits : constant Nat := M * System_Storage_Unit; 8762 Comp : Entity_Id; 8763 8764 begin 8765 Comp := C; 8766 8767 -- For a component inherited in a record extension, the 8768 -- clause is inherited but position and size are not set. 8769 8770 if Is_Base_Type (Etype (P)) 8771 and then Is_Tagged_Type (Etype (P)) 8772 and then Present (Original_Record_Component (Comp)) 8773 then 8774 Comp := Original_Record_Component (Comp); 8775 end if; 8776 8777 if Component_Bit_Offset (Comp) mod Align_In_Bits /= 0 8778 or else Esize (Comp) mod Align_In_Bits /= 0 8779 then 8780 return True; 8781 end if; 8782 end; 8783 end if; 8784 8785 -- Otherwise, for a component reference, test prefix 8786 8787 return Is_Possibly_Unaligned_Object (P); 8788 end; 8789 8790 -- If not a component reference, must be aligned 8791 8792 else 8793 return False; 8794 end if; 8795 end Is_Possibly_Unaligned_Object; 8796 8797 --------------------------------- 8798 -- Is_Possibly_Unaligned_Slice -- 8799 --------------------------------- 8800 8801 function Is_Possibly_Unaligned_Slice (N : Node_Id) return Boolean is 8802 begin 8803 -- Go to renamed object 8804 8805 if Is_Entity_Name (N) 8806 and then Is_Object (Entity (N)) 8807 and then Present (Renamed_Object (Entity (N))) 8808 then 8809 return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (N))); 8810 end if; 8811 8812 -- The reference must be a slice 8813 8814 if Nkind (N) /= N_Slice then 8815 return False; 8816 end if; 8817 8818 -- If it is a slice, then look at the array type being sliced 8819 8820 declare 8821 Sarr : constant Node_Id := Prefix (N); 8822 -- Prefix of the slice, i.e. the array being sliced 8823 8824 Styp : constant Entity_Id := Etype (Prefix (N)); 8825 -- Type of the array being sliced 8826 8827 Pref : Node_Id; 8828 Ptyp : Entity_Id; 8829 8830 begin 8831 -- The problems arise if the array object that is being sliced 8832 -- is a component of a record or array, and we cannot guarantee 8833 -- the alignment of the array within its containing object. 8834 8835 -- To investigate this, we look at successive prefixes to see 8836 -- if we have a worrisome indexed or selected component. 8837 8838 Pref := Sarr; 8839 loop 8840 -- Case of array is part of an indexed component reference 8841 8842 if Nkind (Pref) = N_Indexed_Component then 8843 Ptyp := Etype (Prefix (Pref)); 8844 8845 -- The only problematic case is when the array is packed, in 8846 -- which case we really know nothing about the alignment of 8847 -- individual components. 8848 8849 if Is_Bit_Packed_Array (Ptyp) then 8850 return True; 8851 end if; 8852 8853 -- Case of array is part of a selected component reference 8854 8855 elsif Nkind (Pref) = N_Selected_Component then 8856 Ptyp := Etype (Prefix (Pref)); 8857 8858 -- We are definitely in trouble if the record in question 8859 -- has an alignment, and either we know this alignment is 8860 -- inconsistent with the alignment of the slice, or we don't 8861 -- know what the alignment of the slice should be. But this 8862 -- really matters only if the target has strict alignment. 8863 8864 if Target_Strict_Alignment 8865 and then Known_Alignment (Ptyp) 8866 and then (Unknown_Alignment (Styp) 8867 or else Alignment (Styp) > Alignment (Ptyp)) 8868 then 8869 return True; 8870 end if; 8871 8872 -- We are in potential trouble if the record type is packed. 8873 -- We could special case when we know that the array is the 8874 -- first component, but that's not such a simple case ??? 8875 8876 if Is_Packed (Ptyp) then 8877 return True; 8878 end if; 8879 8880 -- We are in trouble if there is a component clause, and 8881 -- either we do not know the alignment of the slice, or 8882 -- the alignment of the slice is inconsistent with the 8883 -- bit position specified by the component clause. 8884 8885 declare 8886 Field : constant Entity_Id := Entity (Selector_Name (Pref)); 8887 begin 8888 if Present (Component_Clause (Field)) 8889 and then 8890 (Unknown_Alignment (Styp) 8891 or else 8892 (Component_Bit_Offset (Field) mod 8893 (System_Storage_Unit * Alignment (Styp))) /= 0) 8894 then 8895 return True; 8896 end if; 8897 end; 8898 8899 -- For cases other than selected or indexed components we know we 8900 -- are OK, since no issues arise over alignment. 8901 8902 else 8903 return False; 8904 end if; 8905 8906 -- We processed an indexed component or selected component 8907 -- reference that looked safe, so keep checking prefixes. 8908 8909 Pref := Prefix (Pref); 8910 end loop; 8911 end; 8912 end Is_Possibly_Unaligned_Slice; 8913 8914 ------------------------------- 8915 -- Is_Related_To_Func_Return -- 8916 ------------------------------- 8917 8918 function Is_Related_To_Func_Return (Id : Entity_Id) return Boolean is 8919 Expr : constant Node_Id := Related_Expression (Id); 8920 begin 8921 -- In the case of a function with a class-wide result that returns 8922 -- a call to a function with a specific result, we introduce a 8923 -- type conversion for the return expression. We do not want that 8924 -- type conversion to influence the result of this function. 8925 8926 return 8927 Present (Expr) 8928 and then Nkind (Unqual_Conv (Expr)) = N_Explicit_Dereference 8929 and then Nkind (Parent (Expr)) = N_Simple_Return_Statement; 8930 end Is_Related_To_Func_Return; 8931 8932 -------------------------------- 8933 -- Is_Ref_To_Bit_Packed_Array -- 8934 -------------------------------- 8935 8936 function Is_Ref_To_Bit_Packed_Array (N : Node_Id) return Boolean is 8937 Result : Boolean; 8938 Expr : Node_Id; 8939 8940 begin 8941 if Is_Entity_Name (N) 8942 and then Is_Object (Entity (N)) 8943 and then Present (Renamed_Object (Entity (N))) 8944 then 8945 return Is_Ref_To_Bit_Packed_Array (Renamed_Object (Entity (N))); 8946 end if; 8947 8948 if Nkind (N) in N_Indexed_Component | N_Selected_Component then 8949 if Is_Bit_Packed_Array (Etype (Prefix (N))) then 8950 Result := True; 8951 else 8952 Result := Is_Ref_To_Bit_Packed_Array (Prefix (N)); 8953 end if; 8954 8955 if Result and then Nkind (N) = N_Indexed_Component then 8956 Expr := First (Expressions (N)); 8957 while Present (Expr) loop 8958 Force_Evaluation (Expr); 8959 Next (Expr); 8960 end loop; 8961 end if; 8962 8963 return Result; 8964 8965 else 8966 return False; 8967 end if; 8968 end Is_Ref_To_Bit_Packed_Array; 8969 8970 -------------------------------- 8971 -- Is_Ref_To_Bit_Packed_Slice -- 8972 -------------------------------- 8973 8974 function Is_Ref_To_Bit_Packed_Slice (N : Node_Id) return Boolean is 8975 begin 8976 if Nkind (N) = N_Type_Conversion then 8977 return Is_Ref_To_Bit_Packed_Slice (Expression (N)); 8978 8979 elsif Is_Entity_Name (N) 8980 and then Is_Object (Entity (N)) 8981 and then Present (Renamed_Object (Entity (N))) 8982 then 8983 return Is_Ref_To_Bit_Packed_Slice (Renamed_Object (Entity (N))); 8984 8985 elsif Nkind (N) = N_Slice 8986 and then Is_Bit_Packed_Array (Etype (Prefix (N))) 8987 then 8988 return True; 8989 8990 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then 8991 return Is_Ref_To_Bit_Packed_Slice (Prefix (N)); 8992 8993 else 8994 return False; 8995 end if; 8996 end Is_Ref_To_Bit_Packed_Slice; 8997 8998 ----------------------- 8999 -- Is_Renamed_Object -- 9000 ----------------------- 9001 9002 function Is_Renamed_Object (N : Node_Id) return Boolean is 9003 Pnod : constant Node_Id := Parent (N); 9004 Kind : constant Node_Kind := Nkind (Pnod); 9005 begin 9006 if Kind = N_Object_Renaming_Declaration then 9007 return True; 9008 elsif Kind in N_Indexed_Component | N_Selected_Component then 9009 return Is_Renamed_Object (Pnod); 9010 else 9011 return False; 9012 end if; 9013 end Is_Renamed_Object; 9014 9015 -------------------------------------- 9016 -- Is_Secondary_Stack_BIP_Func_Call -- 9017 -------------------------------------- 9018 9019 function Is_Secondary_Stack_BIP_Func_Call (Expr : Node_Id) return Boolean is 9020 Actual : Node_Id; 9021 Call : Node_Id := Expr; 9022 Formal : Node_Id; 9023 Param : Node_Id; 9024 9025 begin 9026 -- Build-in-place calls usually appear in 'reference format. Note that 9027 -- the accessibility check machinery may add an extra 'reference due to 9028 -- side effect removal. 9029 9030 while Nkind (Call) = N_Reference loop 9031 Call := Prefix (Call); 9032 end loop; 9033 9034 Call := Unqual_Conv (Call); 9035 9036 if Is_Build_In_Place_Function_Call (Call) then 9037 9038 -- Examine all parameter associations of the function call 9039 9040 Param := First (Parameter_Associations (Call)); 9041 while Present (Param) loop 9042 if Nkind (Param) = N_Parameter_Association then 9043 Formal := Selector_Name (Param); 9044 Actual := Explicit_Actual_Parameter (Param); 9045 9046 -- A match for BIPalloc => 2 has been found 9047 9048 if Is_Build_In_Place_Entity (Formal) 9049 and then BIP_Suffix_Kind (Formal) = BIP_Alloc_Form 9050 and then Nkind (Actual) = N_Integer_Literal 9051 and then Intval (Actual) = Uint_2 9052 then 9053 return True; 9054 end if; 9055 end if; 9056 9057 Next (Param); 9058 end loop; 9059 end if; 9060 9061 return False; 9062 end Is_Secondary_Stack_BIP_Func_Call; 9063 9064 ------------------------------------- 9065 -- Is_Tag_To_Class_Wide_Conversion -- 9066 ------------------------------------- 9067 9068 function Is_Tag_To_Class_Wide_Conversion 9069 (Obj_Id : Entity_Id) return Boolean 9070 is 9071 Expr : constant Node_Id := Expression (Parent (Obj_Id)); 9072 9073 begin 9074 return 9075 Is_Class_Wide_Type (Etype (Obj_Id)) 9076 and then Present (Expr) 9077 and then Nkind (Expr) = N_Unchecked_Type_Conversion 9078 and then Etype (Expression (Expr)) = RTE (RE_Tag); 9079 end Is_Tag_To_Class_Wide_Conversion; 9080 9081 -------------------------------- 9082 -- Is_Uninitialized_Aggregate -- 9083 -------------------------------- 9084 9085 function Is_Uninitialized_Aggregate 9086 (Exp : Node_Id; 9087 T : Entity_Id) return Boolean 9088 is 9089 Comp : Node_Id; 9090 Comp_Type : Entity_Id; 9091 Typ : Entity_Id; 9092 9093 begin 9094 if Nkind (Exp) /= N_Aggregate then 9095 return False; 9096 end if; 9097 9098 Preanalyze_And_Resolve (Exp, T); 9099 Typ := Etype (Exp); 9100 9101 if No (Typ) 9102 or else Ekind (Typ) /= E_Array_Subtype 9103 or else Present (Expressions (Exp)) 9104 or else No (Component_Associations (Exp)) 9105 then 9106 return False; 9107 else 9108 Comp_Type := Component_Type (Typ); 9109 Comp := First (Component_Associations (Exp)); 9110 9111 if not Box_Present (Comp) 9112 or else Present (Next (Comp)) 9113 then 9114 return False; 9115 end if; 9116 9117 return Is_Scalar_Type (Comp_Type) 9118 and then No (Default_Aspect_Component_Value (Typ)); 9119 end if; 9120 end Is_Uninitialized_Aggregate; 9121 9122 ---------------------------- 9123 -- Is_Untagged_Derivation -- 9124 ---------------------------- 9125 9126 function Is_Untagged_Derivation (T : Entity_Id) return Boolean is 9127 begin 9128 return (not Is_Tagged_Type (T) and then Is_Derived_Type (T)) 9129 or else 9130 (Is_Private_Type (T) and then Present (Full_View (T)) 9131 and then not Is_Tagged_Type (Full_View (T)) 9132 and then Is_Derived_Type (Full_View (T)) 9133 and then Etype (Full_View (T)) /= T); 9134 end Is_Untagged_Derivation; 9135 9136 ------------------------------------ 9137 -- Is_Untagged_Private_Derivation -- 9138 ------------------------------------ 9139 9140 function Is_Untagged_Private_Derivation 9141 (Priv_Typ : Entity_Id; 9142 Full_Typ : Entity_Id) return Boolean 9143 is 9144 begin 9145 return 9146 Present (Priv_Typ) 9147 and then Is_Untagged_Derivation (Priv_Typ) 9148 and then Is_Private_Type (Etype (Priv_Typ)) 9149 and then Present (Full_Typ) 9150 and then Is_Itype (Full_Typ); 9151 end Is_Untagged_Private_Derivation; 9152 9153 ------------------------------ 9154 -- Is_Verifiable_DIC_Pragma -- 9155 ------------------------------ 9156 9157 function Is_Verifiable_DIC_Pragma (Prag : Node_Id) return Boolean is 9158 Args : constant List_Id := Pragma_Argument_Associations (Prag); 9159 9160 begin 9161 -- To qualify as verifiable, a DIC pragma must have a non-null argument 9162 9163 return 9164 Present (Args) 9165 9166 -- If there are args, but the first arg is Empty, then treat the 9167 -- pragma the same as having no args (there may be a second arg that 9168 -- is an implicitly added type arg, and Empty is a placeholder). 9169 9170 and then Present (Get_Pragma_Arg (First (Args))) 9171 9172 and then Nkind (Get_Pragma_Arg (First (Args))) /= N_Null; 9173 end Is_Verifiable_DIC_Pragma; 9174 9175 --------------------------- 9176 -- Is_Volatile_Reference -- 9177 --------------------------- 9178 9179 function Is_Volatile_Reference (N : Node_Id) return Boolean is 9180 begin 9181 -- Only source references are to be treated as volatile, internally 9182 -- generated stuff cannot have volatile external effects. 9183 9184 if not Comes_From_Source (N) then 9185 return False; 9186 9187 -- Never true for reference to a type 9188 9189 elsif Is_Entity_Name (N) and then Is_Type (Entity (N)) then 9190 return False; 9191 9192 -- Never true for a compile time known constant 9193 9194 elsif Compile_Time_Known_Value (N) then 9195 return False; 9196 9197 -- True if object reference with volatile type 9198 9199 elsif Is_Volatile_Object (N) then 9200 return True; 9201 9202 -- True if reference to volatile entity 9203 9204 elsif Is_Entity_Name (N) then 9205 return Treat_As_Volatile (Entity (N)); 9206 9207 -- True for slice of volatile array 9208 9209 elsif Nkind (N) = N_Slice then 9210 return Is_Volatile_Reference (Prefix (N)); 9211 9212 -- True if volatile component 9213 9214 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then 9215 if (Is_Entity_Name (Prefix (N)) 9216 and then Has_Volatile_Components (Entity (Prefix (N)))) 9217 or else (Present (Etype (Prefix (N))) 9218 and then Has_Volatile_Components (Etype (Prefix (N)))) 9219 then 9220 return True; 9221 else 9222 return Is_Volatile_Reference (Prefix (N)); 9223 end if; 9224 9225 -- Otherwise false 9226 9227 else 9228 return False; 9229 end if; 9230 end Is_Volatile_Reference; 9231 9232 -------------------- 9233 -- Kill_Dead_Code -- 9234 -------------------- 9235 9236 procedure Kill_Dead_Code (N : Node_Id; Warn : Boolean := False) is 9237 W : Boolean := Warn; 9238 -- Set False if warnings suppressed 9239 9240 begin 9241 if Present (N) then 9242 Remove_Warning_Messages (N); 9243 9244 -- Update the internal structures of the ABE mechanism in case the 9245 -- dead node is an elaboration scenario. 9246 9247 Kill_Elaboration_Scenario (N); 9248 9249 -- Generate warning if appropriate 9250 9251 if W then 9252 9253 -- We suppress the warning if this code is under control of an 9254 -- if statement, whose condition is a simple identifier, and 9255 -- either we are in an instance, or warnings off is set for this 9256 -- identifier. The reason for killing it in the instance case is 9257 -- that it is common and reasonable for code to be deleted in 9258 -- instances for various reasons. 9259 9260 -- Could we use Is_Statically_Unevaluated here??? 9261 9262 if Nkind (Parent (N)) = N_If_Statement then 9263 declare 9264 C : constant Node_Id := Condition (Parent (N)); 9265 begin 9266 if Nkind (C) = N_Identifier 9267 and then 9268 (In_Instance 9269 or else (Present (Entity (C)) 9270 and then Has_Warnings_Off (Entity (C)))) 9271 then 9272 W := False; 9273 end if; 9274 end; 9275 end if; 9276 9277 -- Generate warning if not suppressed 9278 9279 if W then 9280 Error_Msg_F 9281 ("?t?this code can never be executed and has been deleted!", 9282 N); 9283 end if; 9284 end if; 9285 9286 -- Recurse into block statements and bodies to process declarations 9287 -- and statements. 9288 9289 if Nkind (N) = N_Block_Statement 9290 or else Nkind (N) = N_Subprogram_Body 9291 or else Nkind (N) = N_Package_Body 9292 then 9293 Kill_Dead_Code (Declarations (N), False); 9294 Kill_Dead_Code (Statements (Handled_Statement_Sequence (N))); 9295 9296 if Nkind (N) = N_Subprogram_Body then 9297 Set_Is_Eliminated (Defining_Entity (N)); 9298 end if; 9299 9300 elsif Nkind (N) = N_Package_Declaration then 9301 Kill_Dead_Code (Visible_Declarations (Specification (N))); 9302 Kill_Dead_Code (Private_Declarations (Specification (N))); 9303 9304 -- ??? After this point, Delete_Tree has been called on all 9305 -- declarations in Specification (N), so references to entities 9306 -- therein look suspicious. 9307 9308 declare 9309 E : Entity_Id := First_Entity (Defining_Entity (N)); 9310 9311 begin 9312 while Present (E) loop 9313 if Ekind (E) = E_Operator then 9314 Set_Is_Eliminated (E); 9315 end if; 9316 9317 Next_Entity (E); 9318 end loop; 9319 end; 9320 9321 -- Recurse into composite statement to kill individual statements in 9322 -- particular instantiations. 9323 9324 elsif Nkind (N) = N_If_Statement then 9325 Kill_Dead_Code (Then_Statements (N)); 9326 Kill_Dead_Code (Elsif_Parts (N)); 9327 Kill_Dead_Code (Else_Statements (N)); 9328 9329 elsif Nkind (N) = N_Loop_Statement then 9330 Kill_Dead_Code (Statements (N)); 9331 9332 elsif Nkind (N) = N_Case_Statement then 9333 declare 9334 Alt : Node_Id; 9335 begin 9336 Alt := First (Alternatives (N)); 9337 while Present (Alt) loop 9338 Kill_Dead_Code (Statements (Alt)); 9339 Next (Alt); 9340 end loop; 9341 end; 9342 9343 elsif Nkind (N) = N_Case_Statement_Alternative then 9344 Kill_Dead_Code (Statements (N)); 9345 9346 -- Deal with dead instances caused by deleting instantiations 9347 9348 elsif Nkind (N) in N_Generic_Instantiation then 9349 Remove_Dead_Instance (N); 9350 end if; 9351 end if; 9352 end Kill_Dead_Code; 9353 9354 -- Case where argument is a list of nodes to be killed 9355 9356 procedure Kill_Dead_Code (L : List_Id; Warn : Boolean := False) is 9357 N : Node_Id; 9358 W : Boolean; 9359 9360 begin 9361 W := Warn; 9362 9363 if Is_Non_Empty_List (L) then 9364 N := First (L); 9365 while Present (N) loop 9366 Kill_Dead_Code (N, W); 9367 W := False; 9368 Next (N); 9369 end loop; 9370 end if; 9371 end Kill_Dead_Code; 9372 9373 ----------------------------- 9374 -- Make_CW_Equivalent_Type -- 9375 ----------------------------- 9376 9377 -- Create a record type used as an equivalent of any member of the class 9378 -- which takes its size from exp. 9379 9380 -- Generate the following code: 9381 9382 -- type Equiv_T is record 9383 -- _parent : T (List of discriminant constraints taken from Exp); 9384 -- Ext__50 : Storage_Array (1 .. (Exp'size - Typ'object_size)/8); 9385 -- end Equiv_T; 9386 -- 9387 -- ??? Note that this type does not guarantee same alignment as all 9388 -- derived types 9389 -- 9390 -- Note: for the freezing circuitry, this looks like a record extension, 9391 -- and so we need to make sure that the scalar storage order is the same 9392 -- as that of the parent type. (This does not change anything for the 9393 -- representation of the extension part.) 9394 9395 function Make_CW_Equivalent_Type 9396 (T : Entity_Id; 9397 E : Node_Id) return Entity_Id 9398 is 9399 Loc : constant Source_Ptr := Sloc (E); 9400 Root_Typ : constant Entity_Id := Root_Type (T); 9401 Root_Utyp : constant Entity_Id := Underlying_Type (Root_Typ); 9402 List_Def : constant List_Id := Empty_List; 9403 Comp_List : constant List_Id := New_List; 9404 Equiv_Type : Entity_Id; 9405 Range_Type : Entity_Id; 9406 Str_Type : Entity_Id; 9407 Constr_Root : Entity_Id; 9408 Sizexpr : Node_Id; 9409 9410 begin 9411 -- If the root type is already constrained, there are no discriminants 9412 -- in the expression. 9413 9414 if not Has_Discriminants (Root_Typ) 9415 or else Is_Constrained (Root_Typ) 9416 then 9417 Constr_Root := Root_Typ; 9418 9419 -- At this point in the expansion, nonlimited view of the type 9420 -- must be available, otherwise the error will be reported later. 9421 9422 if From_Limited_With (Constr_Root) 9423 and then Present (Non_Limited_View (Constr_Root)) 9424 then 9425 Constr_Root := Non_Limited_View (Constr_Root); 9426 end if; 9427 9428 else 9429 Constr_Root := Make_Temporary (Loc, 'R'); 9430 9431 -- subtype cstr__n is T (List of discr constraints taken from Exp) 9432 9433 Append_To (List_Def, 9434 Make_Subtype_Declaration (Loc, 9435 Defining_Identifier => Constr_Root, 9436 Subtype_Indication => Make_Subtype_From_Expr (E, Root_Typ))); 9437 end if; 9438 9439 -- Generate the range subtype declaration 9440 9441 Range_Type := Make_Temporary (Loc, 'G'); 9442 9443 if not Is_Interface (Root_Typ) then 9444 9445 -- subtype rg__xx is 9446 -- Storage_Offset range 1 .. (Expr'size - typ'size) / Storage_Unit 9447 9448 Sizexpr := 9449 Make_Op_Subtract (Loc, 9450 Left_Opnd => 9451 Make_Attribute_Reference (Loc, 9452 Prefix => 9453 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)), 9454 Attribute_Name => Name_Size), 9455 Right_Opnd => 9456 Make_Attribute_Reference (Loc, 9457 Prefix => New_Occurrence_Of (Constr_Root, Loc), 9458 Attribute_Name => Name_Object_Size)); 9459 else 9460 -- subtype rg__xx is 9461 -- Storage_Offset range 1 .. Expr'size / Storage_Unit 9462 9463 Sizexpr := 9464 Make_Attribute_Reference (Loc, 9465 Prefix => 9466 OK_Convert_To (T, Duplicate_Subexpr_No_Checks (E)), 9467 Attribute_Name => Name_Size); 9468 end if; 9469 9470 Set_Paren_Count (Sizexpr, 1); 9471 9472 Append_To (List_Def, 9473 Make_Subtype_Declaration (Loc, 9474 Defining_Identifier => Range_Type, 9475 Subtype_Indication => 9476 Make_Subtype_Indication (Loc, 9477 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Offset), Loc), 9478 Constraint => Make_Range_Constraint (Loc, 9479 Range_Expression => 9480 Make_Range (Loc, 9481 Low_Bound => Make_Integer_Literal (Loc, 1), 9482 High_Bound => 9483 Make_Op_Divide (Loc, 9484 Left_Opnd => Sizexpr, 9485 Right_Opnd => Make_Integer_Literal (Loc, 9486 Intval => System_Storage_Unit))))))); 9487 9488 -- subtype str__nn is Storage_Array (rg__x); 9489 9490 Str_Type := Make_Temporary (Loc, 'S'); 9491 Append_To (List_Def, 9492 Make_Subtype_Declaration (Loc, 9493 Defining_Identifier => Str_Type, 9494 Subtype_Indication => 9495 Make_Subtype_Indication (Loc, 9496 Subtype_Mark => New_Occurrence_Of (RTE (RE_Storage_Array), Loc), 9497 Constraint => 9498 Make_Index_Or_Discriminant_Constraint (Loc, 9499 Constraints => 9500 New_List (New_Occurrence_Of (Range_Type, Loc)))))); 9501 9502 -- type Equiv_T is record 9503 -- [ _parent : Tnn; ] 9504 -- E : Str_Type; 9505 -- end Equiv_T; 9506 9507 Equiv_Type := Make_Temporary (Loc, 'T'); 9508 Set_Ekind (Equiv_Type, E_Record_Type); 9509 Set_Parent_Subtype (Equiv_Type, Constr_Root); 9510 9511 -- Set Is_Class_Wide_Equivalent_Type very early to trigger the special 9512 -- treatment for this type. In particular, even though _parent's type 9513 -- is a controlled type or contains controlled components, we do not 9514 -- want to set Has_Controlled_Component on it to avoid making it gain 9515 -- an unwanted _controller component. 9516 9517 Set_Is_Class_Wide_Equivalent_Type (Equiv_Type); 9518 9519 -- A class-wide equivalent type does not require initialization 9520 9521 Set_Suppress_Initialization (Equiv_Type); 9522 9523 if not Is_Interface (Root_Typ) then 9524 Append_To (Comp_List, 9525 Make_Component_Declaration (Loc, 9526 Defining_Identifier => 9527 Make_Defining_Identifier (Loc, Name_uParent), 9528 Component_Definition => 9529 Make_Component_Definition (Loc, 9530 Aliased_Present => False, 9531 Subtype_Indication => New_Occurrence_Of (Constr_Root, Loc)))); 9532 9533 Set_Reverse_Storage_Order 9534 (Equiv_Type, Reverse_Storage_Order (Base_Type (Root_Utyp))); 9535 Set_Reverse_Bit_Order 9536 (Equiv_Type, Reverse_Bit_Order (Base_Type (Root_Utyp))); 9537 end if; 9538 9539 Append_To (Comp_List, 9540 Make_Component_Declaration (Loc, 9541 Defining_Identifier => Make_Temporary (Loc, 'C'), 9542 Component_Definition => 9543 Make_Component_Definition (Loc, 9544 Aliased_Present => False, 9545 Subtype_Indication => New_Occurrence_Of (Str_Type, Loc)))); 9546 9547 Append_To (List_Def, 9548 Make_Full_Type_Declaration (Loc, 9549 Defining_Identifier => Equiv_Type, 9550 Type_Definition => 9551 Make_Record_Definition (Loc, 9552 Component_List => 9553 Make_Component_List (Loc, 9554 Component_Items => Comp_List, 9555 Variant_Part => Empty)))); 9556 9557 -- Suppress all checks during the analysis of the expanded code to avoid 9558 -- the generation of spurious warnings under ZFP run-time. 9559 9560 Insert_Actions (E, List_Def, Suppress => All_Checks); 9561 return Equiv_Type; 9562 end Make_CW_Equivalent_Type; 9563 9564 ------------------------- 9565 -- Make_Invariant_Call -- 9566 ------------------------- 9567 9568 function Make_Invariant_Call (Expr : Node_Id) return Node_Id is 9569 Loc : constant Source_Ptr := Sloc (Expr); 9570 Typ : constant Entity_Id := Base_Type (Etype (Expr)); 9571 pragma Assert (Has_Invariants (Typ)); 9572 Proc_Id : constant Entity_Id := Invariant_Procedure (Typ); 9573 pragma Assert (Present (Proc_Id)); 9574 begin 9575 -- The invariant procedure has a null body if assertions are disabled or 9576 -- Assertion_Policy Ignore is in effect. In that case, generate a null 9577 -- statement instead of a call to the invariant procedure. 9578 9579 if Has_Null_Body (Proc_Id) then 9580 return Make_Null_Statement (Loc); 9581 else 9582 return 9583 Make_Procedure_Call_Statement (Loc, 9584 Name => New_Occurrence_Of (Proc_Id, Loc), 9585 Parameter_Associations => New_List (Relocate_Node (Expr))); 9586 end if; 9587 end Make_Invariant_Call; 9588 9589 ------------------------ 9590 -- Make_Literal_Range -- 9591 ------------------------ 9592 9593 function Make_Literal_Range 9594 (Loc : Source_Ptr; 9595 Literal_Typ : Entity_Id) return Node_Id 9596 is 9597 Lo : constant Node_Id := 9598 New_Copy_Tree (String_Literal_Low_Bound (Literal_Typ)); 9599 Index : constant Entity_Id := Etype (Lo); 9600 Length_Expr : constant Node_Id := 9601 Make_Op_Subtract (Loc, 9602 Left_Opnd => 9603 Make_Integer_Literal (Loc, 9604 Intval => String_Literal_Length (Literal_Typ)), 9605 Right_Opnd => Make_Integer_Literal (Loc, 1)); 9606 9607 Hi : Node_Id; 9608 9609 begin 9610 Set_Analyzed (Lo, False); 9611 9612 if Is_Integer_Type (Index) then 9613 Hi := 9614 Make_Op_Add (Loc, 9615 Left_Opnd => New_Copy_Tree (Lo), 9616 Right_Opnd => Length_Expr); 9617 else 9618 Hi := 9619 Make_Attribute_Reference (Loc, 9620 Attribute_Name => Name_Val, 9621 Prefix => New_Occurrence_Of (Index, Loc), 9622 Expressions => New_List ( 9623 Make_Op_Add (Loc, 9624 Left_Opnd => 9625 Make_Attribute_Reference (Loc, 9626 Attribute_Name => Name_Pos, 9627 Prefix => New_Occurrence_Of (Index, Loc), 9628 Expressions => New_List (New_Copy_Tree (Lo))), 9629 Right_Opnd => Length_Expr))); 9630 end if; 9631 9632 return 9633 Make_Range (Loc, 9634 Low_Bound => Lo, 9635 High_Bound => Hi); 9636 end Make_Literal_Range; 9637 9638 -------------------------- 9639 -- Make_Non_Empty_Check -- 9640 -------------------------- 9641 9642 function Make_Non_Empty_Check 9643 (Loc : Source_Ptr; 9644 N : Node_Id) return Node_Id 9645 is 9646 begin 9647 return 9648 Make_Op_Ne (Loc, 9649 Left_Opnd => 9650 Make_Attribute_Reference (Loc, 9651 Attribute_Name => Name_Length, 9652 Prefix => Duplicate_Subexpr_No_Checks (N, Name_Req => True)), 9653 Right_Opnd => 9654 Make_Integer_Literal (Loc, 0)); 9655 end Make_Non_Empty_Check; 9656 9657 ------------------------- 9658 -- Make_Predicate_Call -- 9659 ------------------------- 9660 9661 -- WARNING: This routine manages Ghost regions. Return statements must be 9662 -- replaced by gotos which jump to the end of the routine and restore the 9663 -- Ghost mode. 9664 9665 function Make_Predicate_Call 9666 (Typ : Entity_Id; 9667 Expr : Node_Id; 9668 Mem : Boolean := False) return Node_Id 9669 is 9670 Loc : constant Source_Ptr := Sloc (Expr); 9671 9672 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; 9673 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; 9674 -- Save the Ghost-related attributes to restore on exit 9675 9676 Call : Node_Id; 9677 Func_Id : Entity_Id; 9678 9679 begin 9680 Func_Id := Predicate_Function (Typ); 9681 pragma Assert (Present (Func_Id)); 9682 9683 -- The related type may be subject to pragma Ghost. Set the mode now to 9684 -- ensure that the call is properly marked as Ghost. 9685 9686 Set_Ghost_Mode (Typ); 9687 9688 -- Call special membership version if requested and available 9689 9690 if Mem and then Present (Predicate_Function_M (Typ)) then 9691 Func_Id := Predicate_Function_M (Typ); 9692 end if; 9693 9694 -- Case of calling normal predicate function 9695 9696 -- If the type is tagged, the expression may be class-wide, in which 9697 -- case it has to be converted to its root type, given that the 9698 -- generated predicate function is not dispatching. The conversion is 9699 -- type-safe and does not need validation, which matters when private 9700 -- extensions are involved. 9701 9702 if Is_Tagged_Type (Typ) then 9703 Call := 9704 Make_Function_Call (Loc, 9705 Name => New_Occurrence_Of (Func_Id, Loc), 9706 Parameter_Associations => 9707 New_List (OK_Convert_To (Typ, Relocate_Node (Expr)))); 9708 else 9709 Call := 9710 Make_Function_Call (Loc, 9711 Name => New_Occurrence_Of (Func_Id, Loc), 9712 Parameter_Associations => New_List (Relocate_Node (Expr))); 9713 end if; 9714 9715 Restore_Ghost_Region (Saved_GM, Saved_IGR); 9716 9717 return Call; 9718 end Make_Predicate_Call; 9719 9720 -------------------------- 9721 -- Make_Predicate_Check -- 9722 -------------------------- 9723 9724 function Make_Predicate_Check 9725 (Typ : Entity_Id; 9726 Expr : Node_Id) return Node_Id 9727 is 9728 Loc : constant Source_Ptr := Sloc (Expr); 9729 9730 procedure Add_Failure_Expression (Args : List_Id); 9731 -- Add the failure expression of pragma Predicate_Failure (if any) to 9732 -- list Args. 9733 9734 ---------------------------- 9735 -- Add_Failure_Expression -- 9736 ---------------------------- 9737 9738 procedure Add_Failure_Expression (Args : List_Id) is 9739 function Failure_Expression return Node_Id; 9740 pragma Inline (Failure_Expression); 9741 -- Find aspect or pragma Predicate_Failure that applies to type Typ 9742 -- and return its expression. Return Empty if no such annotation is 9743 -- available. 9744 9745 function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean; 9746 pragma Inline (Is_OK_PF_Aspect); 9747 -- Determine whether aspect Asp is a suitable Predicate_Failure 9748 -- aspect that applies to type Typ. 9749 9750 function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean; 9751 pragma Inline (Is_OK_PF_Pragma); 9752 -- Determine whether pragma Prag is a suitable Predicate_Failure 9753 -- pragma that applies to type Typ. 9754 9755 procedure Replace_Subtype_Reference (N : Node_Id); 9756 -- Replace the current instance of type Typ denoted by N with 9757 -- expression Expr. 9758 9759 ------------------------ 9760 -- Failure_Expression -- 9761 ------------------------ 9762 9763 function Failure_Expression return Node_Id is 9764 Item : Node_Id; 9765 9766 begin 9767 -- The management of the rep item chain involves "inheritance" of 9768 -- parent type chains. If a parent [sub]type is already subject to 9769 -- pragma Predicate_Failure, then the pragma will also appear in 9770 -- the chain of the child [sub]type, which in turn may possess a 9771 -- pragma of its own. Avoid order-dependent issues by inspecting 9772 -- the rep item chain directly. Note that routine Get_Pragma may 9773 -- return a parent pragma. 9774 9775 Item := First_Rep_Item (Typ); 9776 while Present (Item) loop 9777 9778 -- Predicate_Failure appears as an aspect 9779 9780 if Nkind (Item) = N_Aspect_Specification 9781 and then Is_OK_PF_Aspect (Item) 9782 then 9783 return Expression (Item); 9784 9785 -- Predicate_Failure appears as a pragma 9786 9787 elsif Nkind (Item) = N_Pragma 9788 and then Is_OK_PF_Pragma (Item) 9789 then 9790 return 9791 Get_Pragma_Arg 9792 (Next (First (Pragma_Argument_Associations (Item)))); 9793 end if; 9794 9795 Next_Rep_Item (Item); 9796 end loop; 9797 9798 return Empty; 9799 end Failure_Expression; 9800 9801 --------------------- 9802 -- Is_OK_PF_Aspect -- 9803 --------------------- 9804 9805 function Is_OK_PF_Aspect (Asp : Node_Id) return Boolean is 9806 begin 9807 -- To qualify, the aspect must apply to the type subjected to the 9808 -- predicate check. 9809 9810 return 9811 Chars (Identifier (Asp)) = Name_Predicate_Failure 9812 and then Present (Entity (Asp)) 9813 and then Entity (Asp) = Typ; 9814 end Is_OK_PF_Aspect; 9815 9816 --------------------- 9817 -- Is_OK_PF_Pragma -- 9818 --------------------- 9819 9820 function Is_OK_PF_Pragma (Prag : Node_Id) return Boolean is 9821 Args : constant List_Id := Pragma_Argument_Associations (Prag); 9822 Typ_Arg : Node_Id; 9823 9824 begin 9825 -- Nothing to do when the pragma does not denote Predicate_Failure 9826 9827 if Pragma_Name (Prag) /= Name_Predicate_Failure then 9828 return False; 9829 9830 -- Nothing to do when the pragma lacks arguments, in which case it 9831 -- is illegal. 9832 9833 elsif No (Args) or else Is_Empty_List (Args) then 9834 return False; 9835 end if; 9836 9837 Typ_Arg := Get_Pragma_Arg (First (Args)); 9838 9839 -- To qualify, the local name argument of the pragma must denote 9840 -- the type subjected to the predicate check. 9841 9842 return 9843 Is_Entity_Name (Typ_Arg) 9844 and then Present (Entity (Typ_Arg)) 9845 and then Entity (Typ_Arg) = Typ; 9846 end Is_OK_PF_Pragma; 9847 9848 -------------------------------- 9849 -- Replace_Subtype_Reference -- 9850 -------------------------------- 9851 9852 procedure Replace_Subtype_Reference (N : Node_Id) is 9853 begin 9854 Rewrite (N, New_Copy_Tree (Expr)); 9855 end Replace_Subtype_Reference; 9856 9857 procedure Replace_Subtype_References is 9858 new Replace_Type_References_Generic (Replace_Subtype_Reference); 9859 9860 -- Local variables 9861 9862 PF_Expr : constant Node_Id := Failure_Expression; 9863 Expr : Node_Id; 9864 9865 -- Start of processing for Add_Failure_Expression 9866 9867 begin 9868 if Present (PF_Expr) then 9869 9870 -- Replace any occurrences of the current instance of the type 9871 -- with the object subjected to the predicate check. 9872 9873 Expr := New_Copy_Tree (PF_Expr); 9874 Replace_Subtype_References (Expr, Typ); 9875 9876 -- The failure expression appears as the third argument of the 9877 -- Check pragma. 9878 9879 Append_To (Args, 9880 Make_Pragma_Argument_Association (Loc, 9881 Expression => Expr)); 9882 end if; 9883 end Add_Failure_Expression; 9884 9885 -- Local variables 9886 9887 Args : List_Id; 9888 Nam : Name_Id; 9889 9890 -- Start of processing for Make_Predicate_Check 9891 9892 begin 9893 -- If predicate checks are suppressed, then return a null statement. For 9894 -- this call, we check only the scope setting. If the caller wants to 9895 -- check a specific entity's setting, they must do it manually. 9896 9897 if Predicate_Checks_Suppressed (Empty) then 9898 return Make_Null_Statement (Loc); 9899 end if; 9900 9901 -- Do not generate a check within stream functions and the like. 9902 9903 if not Predicate_Check_In_Scope (Expr) then 9904 return Make_Null_Statement (Loc); 9905 end if; 9906 9907 -- Compute proper name to use, we need to get this right so that the 9908 -- right set of check policies apply to the Check pragma we are making. 9909 9910 if Has_Dynamic_Predicate_Aspect (Typ) then 9911 Nam := Name_Dynamic_Predicate; 9912 elsif Has_Static_Predicate_Aspect (Typ) then 9913 Nam := Name_Static_Predicate; 9914 else 9915 Nam := Name_Predicate; 9916 end if; 9917 9918 Args := New_List ( 9919 Make_Pragma_Argument_Association (Loc, 9920 Expression => Make_Identifier (Loc, Nam)), 9921 Make_Pragma_Argument_Association (Loc, 9922 Expression => Make_Predicate_Call (Typ, Expr))); 9923 9924 -- If the subtype is subject to pragma Predicate_Failure, add the 9925 -- failure expression as an additional parameter. 9926 9927 Add_Failure_Expression (Args); 9928 9929 return 9930 Make_Pragma (Loc, 9931 Chars => Name_Check, 9932 Pragma_Argument_Associations => Args); 9933 end Make_Predicate_Check; 9934 9935 ---------------------------- 9936 -- Make_Subtype_From_Expr -- 9937 ---------------------------- 9938 9939 -- 1. If Expr is an unconstrained array expression, creates 9940 -- Unc_Type(Expr'first(1)..Expr'last(1),..., Expr'first(n)..Expr'last(n)) 9941 9942 -- 2. If Expr is a unconstrained discriminated type expression, creates 9943 -- Unc_Type(Expr.Discr1, ... , Expr.Discr_n) 9944 9945 -- 3. If Expr is class-wide, creates an implicit class-wide subtype 9946 9947 function Make_Subtype_From_Expr 9948 (E : Node_Id; 9949 Unc_Typ : Entity_Id; 9950 Related_Id : Entity_Id := Empty) return Node_Id 9951 is 9952 List_Constr : constant List_Id := New_List; 9953 Loc : constant Source_Ptr := Sloc (E); 9954 D : Entity_Id; 9955 Full_Exp : Node_Id; 9956 Full_Subtyp : Entity_Id; 9957 High_Bound : Entity_Id; 9958 Index_Typ : Entity_Id; 9959 Low_Bound : Entity_Id; 9960 Priv_Subtyp : Entity_Id; 9961 Utyp : Entity_Id; 9962 9963 begin 9964 if Is_Private_Type (Unc_Typ) 9965 and then Has_Unknown_Discriminants (Unc_Typ) 9966 then 9967 -- The caller requests a unique external name for both the private 9968 -- and the full subtype. 9969 9970 if Present (Related_Id) then 9971 Full_Subtyp := 9972 Make_Defining_Identifier (Loc, 9973 Chars => New_External_Name (Chars (Related_Id), 'C')); 9974 Priv_Subtyp := 9975 Make_Defining_Identifier (Loc, 9976 Chars => New_External_Name (Chars (Related_Id), 'P')); 9977 9978 else 9979 Full_Subtyp := Make_Temporary (Loc, 'C'); 9980 Priv_Subtyp := Make_Temporary (Loc, 'P'); 9981 end if; 9982 9983 -- Prepare the subtype completion. Use the base type to find the 9984 -- underlying type because the type may be a generic actual or an 9985 -- explicit subtype. 9986 9987 Utyp := Underlying_Type (Base_Type (Unc_Typ)); 9988 9989 Full_Exp := 9990 Unchecked_Convert_To (Utyp, Duplicate_Subexpr_No_Checks (E)); 9991 Set_Parent (Full_Exp, Parent (E)); 9992 9993 Insert_Action (E, 9994 Make_Subtype_Declaration (Loc, 9995 Defining_Identifier => Full_Subtyp, 9996 Subtype_Indication => Make_Subtype_From_Expr (Full_Exp, Utyp))); 9997 9998 -- Define the dummy private subtype 9999 10000 Set_Ekind (Priv_Subtyp, Subtype_Kind (Ekind (Unc_Typ))); 10001 Set_Etype (Priv_Subtyp, Base_Type (Unc_Typ)); 10002 Set_Scope (Priv_Subtyp, Full_Subtyp); 10003 Set_Is_Constrained (Priv_Subtyp); 10004 Set_Is_Tagged_Type (Priv_Subtyp, Is_Tagged_Type (Unc_Typ)); 10005 Set_Is_Itype (Priv_Subtyp); 10006 Set_Associated_Node_For_Itype (Priv_Subtyp, E); 10007 10008 if Is_Tagged_Type (Priv_Subtyp) then 10009 Set_Class_Wide_Type 10010 (Base_Type (Priv_Subtyp), Class_Wide_Type (Unc_Typ)); 10011 Set_Direct_Primitive_Operations (Priv_Subtyp, 10012 Direct_Primitive_Operations (Unc_Typ)); 10013 end if; 10014 10015 Set_Full_View (Priv_Subtyp, Full_Subtyp); 10016 10017 return New_Occurrence_Of (Priv_Subtyp, Loc); 10018 10019 elsif Is_Array_Type (Unc_Typ) then 10020 Index_Typ := First_Index (Unc_Typ); 10021 for J in 1 .. Number_Dimensions (Unc_Typ) loop 10022 10023 -- Capture the bounds of each index constraint in case the context 10024 -- is an object declaration of an unconstrained type initialized 10025 -- by a function call: 10026 10027 -- Obj : Unconstr_Typ := Func_Call; 10028 10029 -- This scenario requires secondary scope management and the index 10030 -- constraint cannot depend on the temporary used to capture the 10031 -- result of the function call. 10032 10033 -- SS_Mark; 10034 -- Temp : Unconstr_Typ_Ptr := Func_Call'reference; 10035 -- subtype S is Unconstr_Typ (Temp.all'First .. Temp.all'Last); 10036 -- Obj : S := Temp.all; 10037 -- SS_Release; -- Temp is gone at this point, bounds of S are 10038 -- -- non existent. 10039 10040 -- Generate: 10041 -- Low_Bound : constant Base_Type (Index_Typ) := E'First (J); 10042 10043 Low_Bound := Make_Temporary (Loc, 'B'); 10044 Insert_Action (E, 10045 Make_Object_Declaration (Loc, 10046 Defining_Identifier => Low_Bound, 10047 Object_Definition => 10048 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc), 10049 Constant_Present => True, 10050 Expression => 10051 Make_Attribute_Reference (Loc, 10052 Prefix => Duplicate_Subexpr_No_Checks (E), 10053 Attribute_Name => Name_First, 10054 Expressions => New_List ( 10055 Make_Integer_Literal (Loc, J))))); 10056 10057 -- Generate: 10058 -- High_Bound : constant Base_Type (Index_Typ) := E'Last (J); 10059 10060 High_Bound := Make_Temporary (Loc, 'B'); 10061 Insert_Action (E, 10062 Make_Object_Declaration (Loc, 10063 Defining_Identifier => High_Bound, 10064 Object_Definition => 10065 New_Occurrence_Of (Base_Type (Etype (Index_Typ)), Loc), 10066 Constant_Present => True, 10067 Expression => 10068 Make_Attribute_Reference (Loc, 10069 Prefix => Duplicate_Subexpr_No_Checks (E), 10070 Attribute_Name => Name_Last, 10071 Expressions => New_List ( 10072 Make_Integer_Literal (Loc, J))))); 10073 10074 Append_To (List_Constr, 10075 Make_Range (Loc, 10076 Low_Bound => New_Occurrence_Of (Low_Bound, Loc), 10077 High_Bound => New_Occurrence_Of (High_Bound, Loc))); 10078 10079 Next_Index (Index_Typ); 10080 end loop; 10081 10082 elsif Is_Class_Wide_Type (Unc_Typ) then 10083 declare 10084 CW_Subtype : Entity_Id; 10085 EQ_Typ : Entity_Id := Empty; 10086 10087 begin 10088 -- A class-wide equivalent type is not needed on VM targets 10089 -- because the VM back-ends handle the class-wide object 10090 -- initialization itself (and doesn't need or want the 10091 -- additional intermediate type to handle the assignment). 10092 10093 if Expander_Active and then Tagged_Type_Expansion then 10094 10095 -- If this is the class-wide type of a completion that is a 10096 -- record subtype, set the type of the class-wide type to be 10097 -- the full base type, for use in the expanded code for the 10098 -- equivalent type. Should this be done earlier when the 10099 -- completion is analyzed ??? 10100 10101 if Is_Private_Type (Etype (Unc_Typ)) 10102 and then 10103 Ekind (Full_View (Etype (Unc_Typ))) = E_Record_Subtype 10104 then 10105 Set_Etype (Unc_Typ, Base_Type (Full_View (Etype (Unc_Typ)))); 10106 end if; 10107 10108 EQ_Typ := Make_CW_Equivalent_Type (Unc_Typ, E); 10109 end if; 10110 10111 CW_Subtype := New_Class_Wide_Subtype (Unc_Typ, E); 10112 Set_Equivalent_Type (CW_Subtype, EQ_Typ); 10113 Set_Cloned_Subtype (CW_Subtype, Base_Type (Unc_Typ)); 10114 10115 return New_Occurrence_Of (CW_Subtype, Loc); 10116 end; 10117 10118 -- Indefinite record type with discriminants 10119 10120 else 10121 D := First_Discriminant (Unc_Typ); 10122 while Present (D) loop 10123 Append_To (List_Constr, 10124 Make_Selected_Component (Loc, 10125 Prefix => Duplicate_Subexpr_No_Checks (E), 10126 Selector_Name => New_Occurrence_Of (D, Loc))); 10127 10128 Next_Discriminant (D); 10129 end loop; 10130 end if; 10131 10132 return 10133 Make_Subtype_Indication (Loc, 10134 Subtype_Mark => New_Occurrence_Of (Unc_Typ, Loc), 10135 Constraint => 10136 Make_Index_Or_Discriminant_Constraint (Loc, 10137 Constraints => List_Constr)); 10138 end Make_Subtype_From_Expr; 10139 10140 ----------------------------- 10141 -- Make_Variant_Comparison -- 10142 ----------------------------- 10143 10144 function Make_Variant_Comparison 10145 (Loc : Source_Ptr; 10146 Mode : Name_Id; 10147 Curr_Val : Node_Id; 10148 Old_Val : Node_Id) return Node_Id 10149 is 10150 begin 10151 if Mode = Name_Increases then 10152 return Make_Op_Gt (Loc, Curr_Val, Old_Val); 10153 else pragma Assert (Mode = Name_Decreases); 10154 return Make_Op_Lt (Loc, Curr_Val, Old_Val); 10155 end if; 10156 end Make_Variant_Comparison; 10157 10158 --------------- 10159 -- Map_Types -- 10160 --------------- 10161 10162 procedure Map_Types (Parent_Type : Entity_Id; Derived_Type : Entity_Id) is 10163 10164 -- NOTE: Most of the routines in Map_Types are intentionally unnested to 10165 -- avoid deep indentation of code. 10166 10167 -- NOTE: Routines which deal with discriminant mapping operate on the 10168 -- [underlying/record] full view of various types because those views 10169 -- contain all discriminants and stored constraints. 10170 10171 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id); 10172 -- Subsidiary to Map_Primitives. Find a primitive in the inheritance or 10173 -- overriding chain starting from Prim whose dispatching type is parent 10174 -- type Par_Typ and add a mapping between the result and primitive Prim. 10175 10176 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id; 10177 -- Subsidiary to Map_Primitives. Return the next ancestor primitive in 10178 -- the inheritance or overriding chain of subprogram Subp. Return Empty 10179 -- if no such primitive is available. 10180 10181 function Build_Chain 10182 (Par_Typ : Entity_Id; 10183 Deriv_Typ : Entity_Id) return Elist_Id; 10184 -- Subsidiary to Map_Discriminants. Recreate the derivation chain from 10185 -- parent type Par_Typ leading down towards derived type Deriv_Typ. The 10186 -- list has the form: 10187 -- 10188 -- head tail 10189 -- v v 10190 -- <Ancestor_N> -> <Ancestor_N-1> -> <Ancestor_1> -> Deriv_Typ 10191 -- 10192 -- Note that Par_Typ is not part of the resulting derivation chain 10193 10194 function Discriminated_View (Typ : Entity_Id) return Entity_Id; 10195 -- Return the view of type Typ which could potentially contains either 10196 -- the discriminants or stored constraints of the type. 10197 10198 function Find_Discriminant_Value 10199 (Discr : Entity_Id; 10200 Par_Typ : Entity_Id; 10201 Deriv_Typ : Entity_Id; 10202 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id; 10203 -- Subsidiary to Map_Discriminants. Find the value of discriminant Discr 10204 -- in the derivation chain starting from parent type Par_Typ leading to 10205 -- derived type Deriv_Typ. The returned value is one of the following: 10206 -- 10207 -- * An entity which is either a discriminant or a nondiscriminant 10208 -- name, and renames/constraints Discr. 10209 -- 10210 -- * An expression which constraints Discr 10211 -- 10212 -- Typ_Elmt is an element of the derivation chain created by routine 10213 -- Build_Chain and denotes the current ancestor being examined. 10214 10215 procedure Map_Discriminants 10216 (Par_Typ : Entity_Id; 10217 Deriv_Typ : Entity_Id); 10218 -- Map each discriminant of type Par_Typ to a meaningful constraint 10219 -- from the point of view of type Deriv_Typ. 10220 10221 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id); 10222 -- Map each primitive of type Par_Typ to a corresponding primitive of 10223 -- type Deriv_Typ. 10224 10225 ------------------- 10226 -- Add_Primitive -- 10227 ------------------- 10228 10229 procedure Add_Primitive (Prim : Entity_Id; Par_Typ : Entity_Id) is 10230 Par_Prim : Entity_Id; 10231 10232 begin 10233 -- Inspect the inheritance chain through the Alias attribute and the 10234 -- overriding chain through the Overridden_Operation looking for an 10235 -- ancestor primitive with the appropriate dispatching type. 10236 10237 Par_Prim := Prim; 10238 while Present (Par_Prim) loop 10239 exit when Find_Dispatching_Type (Par_Prim) = Par_Typ; 10240 Par_Prim := Ancestor_Primitive (Par_Prim); 10241 end loop; 10242 10243 -- Create a mapping of the form: 10244 10245 -- parent type primitive -> derived type primitive 10246 10247 if Present (Par_Prim) then 10248 Type_Map.Set (Par_Prim, Prim); 10249 end if; 10250 end Add_Primitive; 10251 10252 ------------------------ 10253 -- Ancestor_Primitive -- 10254 ------------------------ 10255 10256 function Ancestor_Primitive (Subp : Entity_Id) return Entity_Id is 10257 Inher_Prim : constant Entity_Id := Alias (Subp); 10258 Over_Prim : constant Entity_Id := Overridden_Operation (Subp); 10259 10260 begin 10261 -- The current subprogram overrides an ancestor primitive 10262 10263 if Present (Over_Prim) then 10264 return Over_Prim; 10265 10266 -- The current subprogram is an internally generated alias of an 10267 -- inherited ancestor primitive. 10268 10269 elsif Present (Inher_Prim) then 10270 return Inher_Prim; 10271 10272 -- Otherwise the current subprogram is the root of the inheritance or 10273 -- overriding chain. 10274 10275 else 10276 return Empty; 10277 end if; 10278 end Ancestor_Primitive; 10279 10280 ----------------- 10281 -- Build_Chain -- 10282 ----------------- 10283 10284 function Build_Chain 10285 (Par_Typ : Entity_Id; 10286 Deriv_Typ : Entity_Id) return Elist_Id 10287 is 10288 Anc_Typ : Entity_Id; 10289 Chain : Elist_Id; 10290 Curr_Typ : Entity_Id; 10291 10292 begin 10293 Chain := New_Elmt_List; 10294 10295 -- Add the derived type to the derivation chain 10296 10297 Prepend_Elmt (Deriv_Typ, Chain); 10298 10299 -- Examine all ancestors starting from the derived type climbing 10300 -- towards parent type Par_Typ. 10301 10302 Curr_Typ := Deriv_Typ; 10303 loop 10304 -- Handle the case where the current type is a record which 10305 -- derives from a subtype. 10306 10307 -- subtype Sub_Typ is Par_Typ ... 10308 -- type Deriv_Typ is Sub_Typ ... 10309 10310 if Ekind (Curr_Typ) = E_Record_Type 10311 and then Present (Parent_Subtype (Curr_Typ)) 10312 then 10313 Anc_Typ := Parent_Subtype (Curr_Typ); 10314 10315 -- Handle the case where the current type is a record subtype of 10316 -- another subtype. 10317 10318 -- subtype Sub_Typ1 is Par_Typ ... 10319 -- subtype Sub_Typ2 is Sub_Typ1 ... 10320 10321 elsif Ekind (Curr_Typ) = E_Record_Subtype 10322 and then Present (Cloned_Subtype (Curr_Typ)) 10323 then 10324 Anc_Typ := Cloned_Subtype (Curr_Typ); 10325 10326 -- Otherwise use the direct parent type 10327 10328 else 10329 Anc_Typ := Etype (Curr_Typ); 10330 end if; 10331 10332 -- Use the first subtype when dealing with itypes 10333 10334 if Is_Itype (Anc_Typ) then 10335 Anc_Typ := First_Subtype (Anc_Typ); 10336 end if; 10337 10338 -- Work with the view which contains the discriminants and stored 10339 -- constraints. 10340 10341 Anc_Typ := Discriminated_View (Anc_Typ); 10342 10343 -- Stop the climb when either the parent type has been reached or 10344 -- there are no more ancestors left to examine. 10345 10346 exit when Anc_Typ = Curr_Typ or else Anc_Typ = Par_Typ; 10347 10348 Prepend_Unique_Elmt (Anc_Typ, Chain); 10349 Curr_Typ := Anc_Typ; 10350 end loop; 10351 10352 return Chain; 10353 end Build_Chain; 10354 10355 ------------------------ 10356 -- Discriminated_View -- 10357 ------------------------ 10358 10359 function Discriminated_View (Typ : Entity_Id) return Entity_Id is 10360 T : Entity_Id; 10361 10362 begin 10363 T := Typ; 10364 10365 -- Use the [underlying] full view when dealing with private types 10366 -- because the view contains all inherited discriminants or stored 10367 -- constraints. 10368 10369 if Is_Private_Type (T) then 10370 if Present (Underlying_Full_View (T)) then 10371 T := Underlying_Full_View (T); 10372 10373 elsif Present (Full_View (T)) then 10374 T := Full_View (T); 10375 end if; 10376 end if; 10377 10378 -- Use the underlying record view when the type is an extenstion of 10379 -- a parent type with unknown discriminants because the view contains 10380 -- all inherited discriminants or stored constraints. 10381 10382 if Ekind (T) = E_Record_Type 10383 and then Present (Underlying_Record_View (T)) 10384 then 10385 T := Underlying_Record_View (T); 10386 end if; 10387 10388 return T; 10389 end Discriminated_View; 10390 10391 ----------------------------- 10392 -- Find_Discriminant_Value -- 10393 ----------------------------- 10394 10395 function Find_Discriminant_Value 10396 (Discr : Entity_Id; 10397 Par_Typ : Entity_Id; 10398 Deriv_Typ : Entity_Id; 10399 Typ_Elmt : Elmt_Id) return Node_Or_Entity_Id 10400 is 10401 Discr_Pos : constant Uint := Discriminant_Number (Discr); 10402 Typ : constant Entity_Id := Node (Typ_Elmt); 10403 10404 function Find_Constraint_Value 10405 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id; 10406 -- Given constraint Constr, find what it denotes. This is either: 10407 -- 10408 -- * An entity which is either a discriminant or a name 10409 -- 10410 -- * An expression 10411 10412 --------------------------- 10413 -- Find_Constraint_Value -- 10414 --------------------------- 10415 10416 function Find_Constraint_Value 10417 (Constr : Node_Or_Entity_Id) return Node_Or_Entity_Id 10418 is 10419 begin 10420 if Nkind (Constr) in N_Entity then 10421 10422 -- The constraint denotes a discriminant of the curren type 10423 -- which renames the ancestor discriminant: 10424 10425 -- vv 10426 -- type Typ (D1 : ...; DN : ...) is 10427 -- new Anc (Discr => D1) with ... 10428 -- ^^ 10429 10430 if Ekind (Constr) = E_Discriminant then 10431 10432 -- The discriminant belongs to derived type Deriv_Typ. This 10433 -- is the final value for the ancestor discriminant as the 10434 -- derivations chain has been fully exhausted. 10435 10436 if Typ = Deriv_Typ then 10437 return Constr; 10438 10439 -- Otherwise the discriminant may be renamed or constrained 10440 -- at a lower level. Continue looking down the derivation 10441 -- chain. 10442 10443 else 10444 return 10445 Find_Discriminant_Value 10446 (Discr => Constr, 10447 Par_Typ => Par_Typ, 10448 Deriv_Typ => Deriv_Typ, 10449 Typ_Elmt => Next_Elmt (Typ_Elmt)); 10450 end if; 10451 10452 -- Otherwise the constraint denotes a reference to some name 10453 -- which results in a Girder discriminant: 10454 10455 -- vvvv 10456 -- Name : ...; 10457 -- type Typ (D1 : ...; DN : ...) is 10458 -- new Anc (Discr => Name) with ... 10459 -- ^^^^ 10460 10461 -- Return the name as this is the proper constraint of the 10462 -- discriminant. 10463 10464 else 10465 return Constr; 10466 end if; 10467 10468 -- The constraint denotes a reference to a name 10469 10470 elsif Is_Entity_Name (Constr) then 10471 return Find_Constraint_Value (Entity (Constr)); 10472 10473 -- Otherwise the current constraint is an expression which yields 10474 -- a Girder discriminant: 10475 10476 -- type Typ (D1 : ...; DN : ...) is 10477 -- new Anc (Discr => <expression>) with ... 10478 -- ^^^^^^^^^^ 10479 10480 -- Return the expression as this is the proper constraint of the 10481 -- discriminant. 10482 10483 else 10484 return Constr; 10485 end if; 10486 end Find_Constraint_Value; 10487 10488 -- Local variables 10489 10490 Constrs : constant Elist_Id := Stored_Constraint (Typ); 10491 10492 Constr_Elmt : Elmt_Id; 10493 Pos : Uint; 10494 Typ_Discr : Entity_Id; 10495 10496 -- Start of processing for Find_Discriminant_Value 10497 10498 begin 10499 -- The algorithm for finding the value of a discriminant works as 10500 -- follows. First, it recreates the derivation chain from Par_Typ 10501 -- to Deriv_Typ as a list: 10502 10503 -- Par_Typ (shown for completeness) 10504 -- v 10505 -- Ancestor_N <-- head of chain 10506 -- v 10507 -- Ancestor_1 10508 -- v 10509 -- Deriv_Typ <-- tail of chain 10510 10511 -- The algorithm then traces the fate of a parent discriminant down 10512 -- the derivation chain. At each derivation level, the discriminant 10513 -- may be either inherited or constrained. 10514 10515 -- 1) Discriminant is inherited: there are two cases, depending on 10516 -- which type is inheriting. 10517 10518 -- 1.1) Deriv_Typ is inheriting: 10519 10520 -- type Ancestor (D_1 : ...) is tagged ... 10521 -- type Deriv_Typ is new Ancestor ... 10522 10523 -- In this case the inherited discriminant is the final value of 10524 -- the parent discriminant because the end of the derivation chain 10525 -- has been reached. 10526 10527 -- 1.2) Some other type is inheriting: 10528 10529 -- type Ancestor_1 (D_1 : ...) is tagged ... 10530 -- type Ancestor_2 is new Ancestor_1 ... 10531 10532 -- In this case the algorithm continues to trace the fate of the 10533 -- inherited discriminant down the derivation chain because it may 10534 -- be further inherited or constrained. 10535 10536 -- 2) Discriminant is constrained: there are three cases, depending 10537 -- on what the constraint is. 10538 10539 -- 2.1) The constraint is another discriminant (aka renaming): 10540 10541 -- type Ancestor_1 (D_1 : ...) is tagged ... 10542 -- type Ancestor_2 (D_2 : ...) is new Ancestor_1 (D_1 => D_2) ... 10543 10544 -- In this case the constraining discriminant becomes the one to 10545 -- track down the derivation chain. The algorithm already knows 10546 -- that D_2 constrains D_1, therefore if the algorithm finds the 10547 -- value of D_2, then this would also be the value for D_1. 10548 10549 -- 2.2) The constraint is a name (aka Girder): 10550 10551 -- Name : ... 10552 -- type Ancestor_1 (D_1 : ...) is tagged ... 10553 -- type Ancestor_2 is new Ancestor_1 (D_1 => Name) ... 10554 10555 -- In this case the name is the final value of D_1 because the 10556 -- discriminant cannot be further constrained. 10557 10558 -- 2.3) The constraint is an expression (aka Girder): 10559 10560 -- type Ancestor_1 (D_1 : ...) is tagged ... 10561 -- type Ancestor_2 is new Ancestor_1 (D_1 => 1 + 2) ... 10562 10563 -- Similar to 2.2, the expression is the final value of D_1 10564 10565 Pos := Uint_1; 10566 10567 -- When a derived type constrains its parent type, all constaints 10568 -- appear in the Stored_Constraint list. Examine the list looking 10569 -- for a positional match. 10570 10571 if Present (Constrs) then 10572 Constr_Elmt := First_Elmt (Constrs); 10573 while Present (Constr_Elmt) loop 10574 10575 -- The position of the current constraint matches that of the 10576 -- ancestor discriminant. 10577 10578 if Pos = Discr_Pos then 10579 return Find_Constraint_Value (Node (Constr_Elmt)); 10580 end if; 10581 10582 Next_Elmt (Constr_Elmt); 10583 Pos := Pos + 1; 10584 end loop; 10585 10586 -- Otherwise the derived type does not constraint its parent type in 10587 -- which case it inherits the parent discriminants. 10588 10589 else 10590 Typ_Discr := First_Discriminant (Typ); 10591 while Present (Typ_Discr) loop 10592 10593 -- The position of the current discriminant matches that of the 10594 -- ancestor discriminant. 10595 10596 if Pos = Discr_Pos then 10597 return Find_Constraint_Value (Typ_Discr); 10598 end if; 10599 10600 Next_Discriminant (Typ_Discr); 10601 Pos := Pos + 1; 10602 end loop; 10603 end if; 10604 10605 -- A discriminant must always have a corresponding value. This is 10606 -- either another discriminant, a name, or an expression. If this 10607 -- point is reached, them most likely the derivation chain employs 10608 -- the wrong views of types. 10609 10610 pragma Assert (False); 10611 10612 return Empty; 10613 end Find_Discriminant_Value; 10614 10615 ----------------------- 10616 -- Map_Discriminants -- 10617 ----------------------- 10618 10619 procedure Map_Discriminants 10620 (Par_Typ : Entity_Id; 10621 Deriv_Typ : Entity_Id) 10622 is 10623 Deriv_Chain : constant Elist_Id := Build_Chain (Par_Typ, Deriv_Typ); 10624 10625 Discr : Entity_Id; 10626 Discr_Val : Node_Or_Entity_Id; 10627 10628 begin 10629 -- Examine each discriminant of parent type Par_Typ and find a 10630 -- suitable value for it from the point of view of derived type 10631 -- Deriv_Typ. 10632 10633 if Has_Discriminants (Par_Typ) then 10634 Discr := First_Discriminant (Par_Typ); 10635 while Present (Discr) loop 10636 Discr_Val := 10637 Find_Discriminant_Value 10638 (Discr => Discr, 10639 Par_Typ => Par_Typ, 10640 Deriv_Typ => Deriv_Typ, 10641 Typ_Elmt => First_Elmt (Deriv_Chain)); 10642 10643 -- Create a mapping of the form: 10644 10645 -- parent type discriminant -> value 10646 10647 Type_Map.Set (Discr, Discr_Val); 10648 10649 Next_Discriminant (Discr); 10650 end loop; 10651 end if; 10652 end Map_Discriminants; 10653 10654 -------------------- 10655 -- Map_Primitives -- 10656 -------------------- 10657 10658 procedure Map_Primitives (Par_Typ : Entity_Id; Deriv_Typ : Entity_Id) is 10659 Deriv_Prim : Entity_Id; 10660 Par_Prim : Entity_Id; 10661 Par_Prims : Elist_Id; 10662 Prim_Elmt : Elmt_Id; 10663 10664 begin 10665 -- Inspect the primitives of the derived type and determine whether 10666 -- they relate to the primitives of the parent type. If there is a 10667 -- meaningful relation, create a mapping of the form: 10668 10669 -- parent type primitive -> perived type primitive 10670 10671 if Present (Direct_Primitive_Operations (Deriv_Typ)) then 10672 Prim_Elmt := First_Elmt (Direct_Primitive_Operations (Deriv_Typ)); 10673 while Present (Prim_Elmt) loop 10674 Deriv_Prim := Node (Prim_Elmt); 10675 10676 if Is_Subprogram (Deriv_Prim) 10677 and then Find_Dispatching_Type (Deriv_Prim) = Deriv_Typ 10678 then 10679 Add_Primitive (Deriv_Prim, Par_Typ); 10680 end if; 10681 10682 Next_Elmt (Prim_Elmt); 10683 end loop; 10684 end if; 10685 10686 -- If the parent operation is an interface operation, the overriding 10687 -- indicator is not present. Instead, we get from the interface 10688 -- operation the primitive of the current type that implements it. 10689 10690 if Is_Interface (Par_Typ) then 10691 Par_Prims := Collect_Primitive_Operations (Par_Typ); 10692 10693 if Present (Par_Prims) then 10694 Prim_Elmt := First_Elmt (Par_Prims); 10695 10696 while Present (Prim_Elmt) loop 10697 Par_Prim := Node (Prim_Elmt); 10698 Deriv_Prim := 10699 Find_Primitive_Covering_Interface (Deriv_Typ, Par_Prim); 10700 10701 if Present (Deriv_Prim) then 10702 Type_Map.Set (Par_Prim, Deriv_Prim); 10703 end if; 10704 10705 Next_Elmt (Prim_Elmt); 10706 end loop; 10707 end if; 10708 end if; 10709 end Map_Primitives; 10710 10711 -- Start of processing for Map_Types 10712 10713 begin 10714 -- Nothing to do if there are no types to work with 10715 10716 if No (Parent_Type) or else No (Derived_Type) then 10717 return; 10718 10719 -- Nothing to do if the mapping already exists 10720 10721 elsif Type_Map.Get (Parent_Type) = Derived_Type then 10722 return; 10723 10724 -- Nothing to do if both types are not tagged. Note that untagged types 10725 -- do not have primitive operations and their discriminants are already 10726 -- handled by gigi. 10727 10728 elsif not Is_Tagged_Type (Parent_Type) 10729 or else not Is_Tagged_Type (Derived_Type) 10730 then 10731 return; 10732 end if; 10733 10734 -- Create a mapping of the form 10735 10736 -- parent type -> derived type 10737 10738 -- to prevent any subsequent attempts to produce the same relations 10739 10740 Type_Map.Set (Parent_Type, Derived_Type); 10741 10742 -- Create mappings of the form 10743 10744 -- parent type discriminant -> derived type discriminant 10745 -- <or> 10746 -- parent type discriminant -> constraint 10747 10748 -- Note that mapping of discriminants breaks privacy because it needs to 10749 -- work with those views which contains the discriminants and any stored 10750 -- constraints. 10751 10752 Map_Discriminants 10753 (Par_Typ => Discriminated_View (Parent_Type), 10754 Deriv_Typ => Discriminated_View (Derived_Type)); 10755 10756 -- Create mappings of the form 10757 10758 -- parent type primitive -> derived type primitive 10759 10760 Map_Primitives 10761 (Par_Typ => Parent_Type, 10762 Deriv_Typ => Derived_Type); 10763 end Map_Types; 10764 10765 ---------------------------- 10766 -- Matching_Standard_Type -- 10767 ---------------------------- 10768 10769 function Matching_Standard_Type (Typ : Entity_Id) return Entity_Id is 10770 pragma Assert (Is_Scalar_Type (Typ)); 10771 Siz : constant Uint := Esize (Typ); 10772 10773 begin 10774 -- Floating-point cases 10775 10776 if Is_Floating_Point_Type (Typ) then 10777 if Siz <= Esize (Standard_Short_Float) then 10778 return Standard_Short_Float; 10779 elsif Siz <= Esize (Standard_Float) then 10780 return Standard_Float; 10781 elsif Siz <= Esize (Standard_Long_Float) then 10782 return Standard_Long_Float; 10783 elsif Siz <= Esize (Standard_Long_Long_Float) then 10784 return Standard_Long_Long_Float; 10785 else 10786 raise Program_Error; 10787 end if; 10788 10789 -- Integer cases (includes fixed-point types) 10790 10791 -- Unsigned integer cases (includes normal enumeration types) 10792 10793 else 10794 return Small_Integer_Type_For (Siz, Is_Unsigned_Type (Typ)); 10795 end if; 10796 end Matching_Standard_Type; 10797 10798 ----------------------------- 10799 -- May_Generate_Large_Temp -- 10800 ----------------------------- 10801 10802 -- At the current time, the only types that we return False for (i.e. where 10803 -- we decide we know they cannot generate large temps) are ones where we 10804 -- know the size is 256 bits or less at compile time, and we are still not 10805 -- doing a thorough job on arrays and records ??? 10806 10807 function May_Generate_Large_Temp (Typ : Entity_Id) return Boolean is 10808 begin 10809 if not Size_Known_At_Compile_Time (Typ) then 10810 return False; 10811 10812 elsif Esize (Typ) /= 0 and then Esize (Typ) <= 256 then 10813 return False; 10814 10815 elsif Is_Array_Type (Typ) 10816 and then Present (Packed_Array_Impl_Type (Typ)) 10817 then 10818 return May_Generate_Large_Temp (Packed_Array_Impl_Type (Typ)); 10819 10820 -- We could do more here to find other small types ??? 10821 10822 else 10823 return True; 10824 end if; 10825 end May_Generate_Large_Temp; 10826 10827 -------------------------------------------- 10828 -- Needs_Conditional_Null_Excluding_Check -- 10829 -------------------------------------------- 10830 10831 function Needs_Conditional_Null_Excluding_Check 10832 (Typ : Entity_Id) return Boolean 10833 is 10834 begin 10835 return 10836 Is_Array_Type (Typ) and then Can_Never_Be_Null (Component_Type (Typ)); 10837 end Needs_Conditional_Null_Excluding_Check; 10838 10839 ---------------------------- 10840 -- Needs_Constant_Address -- 10841 ---------------------------- 10842 10843 function Needs_Constant_Address 10844 (Decl : Node_Id; 10845 Typ : Entity_Id) return Boolean 10846 is 10847 begin 10848 -- If we have no initialization of any kind, then we don't need to place 10849 -- any restrictions on the address clause, because the object will be 10850 -- elaborated after the address clause is evaluated. This happens if the 10851 -- declaration has no initial expression, or the type has no implicit 10852 -- initialization, or the object is imported. 10853 10854 -- The same holds for all initialized scalar types and all access types. 10855 -- Packed bit array types of size up to the maximum integer size are 10856 -- represented using a modular type with an initialization (to zero) and 10857 -- can be processed like other initialized scalar types. 10858 10859 -- If the type is controlled, code to attach the object to a 10860 -- finalization chain is generated at the point of declaration, and 10861 -- therefore the elaboration of the object cannot be delayed: the 10862 -- address expression must be a constant. 10863 10864 if No (Expression (Decl)) 10865 and then not Needs_Finalization (Typ) 10866 and then 10867 (not Has_Non_Null_Base_Init_Proc (Typ) 10868 or else Is_Imported (Defining_Identifier (Decl))) 10869 then 10870 return False; 10871 10872 elsif (Present (Expression (Decl)) and then Is_Scalar_Type (Typ)) 10873 or else Is_Access_Type (Typ) 10874 or else 10875 (Is_Bit_Packed_Array (Typ) 10876 and then Is_Modular_Integer_Type (Packed_Array_Impl_Type (Typ))) 10877 then 10878 return False; 10879 10880 else 10881 -- Otherwise, we require the address clause to be constant because 10882 -- the call to the initialization procedure (or the attach code) has 10883 -- to happen at the point of the declaration. 10884 10885 -- Actually the IP call has been moved to the freeze actions anyway, 10886 -- so maybe we can relax this restriction??? 10887 10888 return True; 10889 end if; 10890 end Needs_Constant_Address; 10891 10892 ---------------------------- 10893 -- New_Class_Wide_Subtype -- 10894 ---------------------------- 10895 10896 function New_Class_Wide_Subtype 10897 (CW_Typ : Entity_Id; 10898 N : Node_Id) return Entity_Id 10899 is 10900 Res : constant Entity_Id := Create_Itype (E_Void, N); 10901 10902 -- Capture relevant attributes of the class-wide subtype which must be 10903 -- restored after the copy. 10904 10905 Res_Chars : constant Name_Id := Chars (Res); 10906 Res_Is_CGE : constant Boolean := Is_Checked_Ghost_Entity (Res); 10907 Res_Is_IGE : constant Boolean := Is_Ignored_Ghost_Entity (Res); 10908 Res_Is_IGN : constant Boolean := Is_Ignored_Ghost_Node (Res); 10909 Res_Scope : constant Entity_Id := Scope (Res); 10910 10911 begin 10912 Copy_Node (CW_Typ, Res); 10913 10914 -- Restore the relevant attributes of the class-wide subtype 10915 10916 Set_Chars (Res, Res_Chars); 10917 Set_Is_Checked_Ghost_Entity (Res, Res_Is_CGE); 10918 Set_Is_Ignored_Ghost_Entity (Res, Res_Is_IGE); 10919 Set_Is_Ignored_Ghost_Node (Res, Res_Is_IGN); 10920 Set_Scope (Res, Res_Scope); 10921 10922 -- Decorate the class-wide subtype 10923 10924 Set_Associated_Node_For_Itype (Res, N); 10925 Set_Comes_From_Source (Res, False); 10926 Set_Ekind (Res, E_Class_Wide_Subtype); 10927 Set_Etype (Res, Base_Type (CW_Typ)); 10928 Set_Freeze_Node (Res, Empty); 10929 Set_Is_Frozen (Res, False); 10930 Set_Is_Itype (Res); 10931 Set_Is_Public (Res, False); 10932 Set_Next_Entity (Res, Empty); 10933 Set_Prev_Entity (Res, Empty); 10934 Set_Sloc (Res, Sloc (N)); 10935 10936 Set_Public_Status (Res); 10937 10938 return Res; 10939 end New_Class_Wide_Subtype; 10940 10941 ----------------------------------- 10942 -- OK_To_Do_Constant_Replacement -- 10943 ----------------------------------- 10944 10945 function OK_To_Do_Constant_Replacement (E : Entity_Id) return Boolean is 10946 ES : constant Entity_Id := Scope (E); 10947 CS : Entity_Id; 10948 10949 begin 10950 -- Do not replace statically allocated objects, because they may be 10951 -- modified outside the current scope. 10952 10953 if Is_Statically_Allocated (E) then 10954 return False; 10955 10956 -- Do not replace aliased or volatile objects, since we don't know what 10957 -- else might change the value. 10958 10959 elsif Is_Aliased (E) or else Treat_As_Volatile (E) then 10960 return False; 10961 10962 -- Debug flag -gnatdM disconnects this optimization 10963 10964 elsif Debug_Flag_MM then 10965 return False; 10966 10967 -- Otherwise check scopes 10968 10969 else 10970 CS := Current_Scope; 10971 10972 loop 10973 -- If we are in right scope, replacement is safe 10974 10975 if CS = ES then 10976 return True; 10977 10978 -- Packages do not affect the determination of safety 10979 10980 elsif Ekind (CS) = E_Package then 10981 exit when CS = Standard_Standard; 10982 CS := Scope (CS); 10983 10984 -- Blocks do not affect the determination of safety 10985 10986 elsif Ekind (CS) = E_Block then 10987 CS := Scope (CS); 10988 10989 -- Loops do not affect the determination of safety. Note that we 10990 -- kill all current values on entry to a loop, so we are just 10991 -- talking about processing within a loop here. 10992 10993 elsif Ekind (CS) = E_Loop then 10994 CS := Scope (CS); 10995 10996 -- Otherwise, the reference is dubious, and we cannot be sure that 10997 -- it is safe to do the replacement. 10998 10999 else 11000 exit; 11001 end if; 11002 end loop; 11003 11004 return False; 11005 end if; 11006 end OK_To_Do_Constant_Replacement; 11007 11008 ------------------------------------ 11009 -- Possible_Bit_Aligned_Component -- 11010 ------------------------------------ 11011 11012 function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is 11013 begin 11014 -- Do not process an unanalyzed node because it is not yet decorated and 11015 -- most checks performed below will fail. 11016 11017 if not Analyzed (N) then 11018 return False; 11019 end if; 11020 11021 -- There are never alignment issues in CodePeer mode 11022 11023 if CodePeer_Mode then 11024 return False; 11025 end if; 11026 11027 case Nkind (N) is 11028 11029 -- Case of indexed component 11030 11031 when N_Indexed_Component => 11032 declare 11033 P : constant Node_Id := Prefix (N); 11034 Ptyp : constant Entity_Id := Etype (P); 11035 11036 begin 11037 -- If we know the component size and it is not larger than the 11038 -- maximum integer size, then we are OK. The back end does the 11039 -- assignment of small misaligned objects correctly. 11040 11041 if Known_Static_Component_Size (Ptyp) 11042 and then Component_Size (Ptyp) <= System_Max_Integer_Size 11043 then 11044 return False; 11045 11046 -- Otherwise, we need to test the prefix, to see if we are 11047 -- indexing from a possibly unaligned component. 11048 11049 else 11050 return Possible_Bit_Aligned_Component (P); 11051 end if; 11052 end; 11053 11054 -- Case of selected component 11055 11056 when N_Selected_Component => 11057 declare 11058 P : constant Node_Id := Prefix (N); 11059 Comp : constant Entity_Id := Entity (Selector_Name (N)); 11060 11061 begin 11062 -- This is the crucial test: if the component itself causes 11063 -- trouble, then we can stop and return True. 11064 11065 if Component_May_Be_Bit_Aligned (Comp) then 11066 return True; 11067 11068 -- Otherwise, we need to test the prefix, to see if we are 11069 -- selecting from a possibly unaligned component. 11070 11071 else 11072 return Possible_Bit_Aligned_Component (P); 11073 end if; 11074 end; 11075 11076 -- For a slice, test the prefix, if that is possibly misaligned, 11077 -- then for sure the slice is. 11078 11079 when N_Slice => 11080 return Possible_Bit_Aligned_Component (Prefix (N)); 11081 11082 -- For an unchecked conversion, check whether the expression may 11083 -- be bit aligned. 11084 11085 when N_Unchecked_Type_Conversion => 11086 return Possible_Bit_Aligned_Component (Expression (N)); 11087 11088 -- If we have none of the above, it means that we have fallen off the 11089 -- top testing prefixes recursively, and we now have a stand alone 11090 -- object, where we don't have a problem, unless this is a renaming, 11091 -- in which case we need to look into the renamed object. 11092 11093 when others => 11094 if Is_Entity_Name (N) 11095 and then Present (Renamed_Object (Entity (N))) 11096 then 11097 return 11098 Possible_Bit_Aligned_Component (Renamed_Object (Entity (N))); 11099 else 11100 return False; 11101 end if; 11102 end case; 11103 end Possible_Bit_Aligned_Component; 11104 11105 ----------------------------------------------- 11106 -- Process_Statements_For_Controlled_Objects -- 11107 ----------------------------------------------- 11108 11109 procedure Process_Statements_For_Controlled_Objects (N : Node_Id) is 11110 Loc : constant Source_Ptr := Sloc (N); 11111 11112 function Are_Wrapped (L : List_Id) return Boolean; 11113 -- Determine whether list L contains only one statement which is a block 11114 11115 function Wrap_Statements_In_Block 11116 (L : List_Id; 11117 Scop : Entity_Id := Current_Scope) return Node_Id; 11118 -- Given a list of statements L, wrap it in a block statement and return 11119 -- the generated node. Scop is either the current scope or the scope of 11120 -- the context (if applicable). 11121 11122 ----------------- 11123 -- Are_Wrapped -- 11124 ----------------- 11125 11126 function Are_Wrapped (L : List_Id) return Boolean is 11127 Stmt : constant Node_Id := First (L); 11128 begin 11129 return 11130 Present (Stmt) 11131 and then No (Next (Stmt)) 11132 and then Nkind (Stmt) = N_Block_Statement; 11133 end Are_Wrapped; 11134 11135 ------------------------------ 11136 -- Wrap_Statements_In_Block -- 11137 ------------------------------ 11138 11139 function Wrap_Statements_In_Block 11140 (L : List_Id; 11141 Scop : Entity_Id := Current_Scope) return Node_Id 11142 is 11143 Block_Id : Entity_Id; 11144 Block_Nod : Node_Id; 11145 Iter_Loop : Entity_Id; 11146 11147 begin 11148 Block_Nod := 11149 Make_Block_Statement (Loc, 11150 Declarations => No_List, 11151 Handled_Statement_Sequence => 11152 Make_Handled_Sequence_Of_Statements (Loc, 11153 Statements => L)); 11154 11155 -- Create a label for the block in case the block needs to manage the 11156 -- secondary stack. A label allows for flag Uses_Sec_Stack to be set. 11157 11158 Add_Block_Identifier (Block_Nod, Block_Id); 11159 11160 -- When wrapping the statements of an iterator loop, check whether 11161 -- the loop requires secondary stack management and if so, propagate 11162 -- the appropriate flags to the block. This ensures that the cursor 11163 -- is properly cleaned up at each iteration of the loop. 11164 11165 Iter_Loop := Find_Enclosing_Iterator_Loop (Scop); 11166 11167 if Present (Iter_Loop) then 11168 Set_Uses_Sec_Stack (Block_Id, Uses_Sec_Stack (Iter_Loop)); 11169 11170 -- Secondary stack reclamation is suppressed when the associated 11171 -- iterator loop contains a return statement which uses the stack. 11172 11173 Set_Sec_Stack_Needed_For_Return 11174 (Block_Id, Sec_Stack_Needed_For_Return (Iter_Loop)); 11175 end if; 11176 11177 return Block_Nod; 11178 end Wrap_Statements_In_Block; 11179 11180 -- Local variables 11181 11182 Block : Node_Id; 11183 11184 -- Start of processing for Process_Statements_For_Controlled_Objects 11185 11186 begin 11187 -- Whenever a non-handled statement list is wrapped in a block, the 11188 -- block must be explicitly analyzed to redecorate all entities in the 11189 -- list and ensure that a finalizer is properly built. 11190 11191 case Nkind (N) is 11192 when N_Conditional_Entry_Call 11193 | N_Elsif_Part 11194 | N_If_Statement 11195 | N_Selective_Accept 11196 => 11197 -- Check the "then statements" for elsif parts and if statements 11198 11199 if Nkind (N) in N_Elsif_Part | N_If_Statement 11200 and then not Is_Empty_List (Then_Statements (N)) 11201 and then not Are_Wrapped (Then_Statements (N)) 11202 and then Requires_Cleanup_Actions 11203 (L => Then_Statements (N), 11204 Lib_Level => False, 11205 Nested_Constructs => False) 11206 then 11207 Block := Wrap_Statements_In_Block (Then_Statements (N)); 11208 Set_Then_Statements (N, New_List (Block)); 11209 11210 Analyze (Block); 11211 end if; 11212 11213 -- Check the "else statements" for conditional entry calls, if 11214 -- statements and selective accepts. 11215 11216 if Nkind (N) in 11217 N_Conditional_Entry_Call | N_If_Statement | N_Selective_Accept 11218 and then not Is_Empty_List (Else_Statements (N)) 11219 and then not Are_Wrapped (Else_Statements (N)) 11220 and then Requires_Cleanup_Actions 11221 (L => Else_Statements (N), 11222 Lib_Level => False, 11223 Nested_Constructs => False) 11224 then 11225 Block := Wrap_Statements_In_Block (Else_Statements (N)); 11226 Set_Else_Statements (N, New_List (Block)); 11227 11228 Analyze (Block); 11229 end if; 11230 11231 when N_Abortable_Part 11232 | N_Accept_Alternative 11233 | N_Case_Statement_Alternative 11234 | N_Delay_Alternative 11235 | N_Entry_Call_Alternative 11236 | N_Exception_Handler 11237 | N_Loop_Statement 11238 | N_Triggering_Alternative 11239 => 11240 if not Is_Empty_List (Statements (N)) 11241 and then not Are_Wrapped (Statements (N)) 11242 and then Requires_Cleanup_Actions 11243 (L => Statements (N), 11244 Lib_Level => False, 11245 Nested_Constructs => False) 11246 then 11247 if Nkind (N) = N_Loop_Statement 11248 and then Present (Identifier (N)) 11249 then 11250 Block := 11251 Wrap_Statements_In_Block 11252 (L => Statements (N), 11253 Scop => Entity (Identifier (N))); 11254 else 11255 Block := Wrap_Statements_In_Block (Statements (N)); 11256 end if; 11257 11258 Set_Statements (N, New_List (Block)); 11259 Analyze (Block); 11260 end if; 11261 11262 -- Could be e.g. a loop that was transformed into a block or null 11263 -- statement. Do nothing for terminate alternatives. 11264 11265 when N_Block_Statement 11266 | N_Null_Statement 11267 | N_Terminate_Alternative 11268 => 11269 null; 11270 11271 when others => 11272 raise Program_Error; 11273 end case; 11274 end Process_Statements_For_Controlled_Objects; 11275 11276 ------------------ 11277 -- Power_Of_Two -- 11278 ------------------ 11279 11280 function Power_Of_Two (N : Node_Id) return Nat is 11281 Typ : constant Entity_Id := Etype (N); 11282 pragma Assert (Is_Integer_Type (Typ)); 11283 11284 Siz : constant Nat := UI_To_Int (Esize (Typ)); 11285 Val : Uint; 11286 11287 begin 11288 if not Compile_Time_Known_Value (N) then 11289 return 0; 11290 11291 else 11292 Val := Expr_Value (N); 11293 for J in 1 .. Siz - 1 loop 11294 if Val = Uint_2 ** J then 11295 return J; 11296 end if; 11297 end loop; 11298 11299 return 0; 11300 end if; 11301 end Power_Of_Two; 11302 11303 ---------------------- 11304 -- Remove_Init_Call -- 11305 ---------------------- 11306 11307 function Remove_Init_Call 11308 (Var : Entity_Id; 11309 Rep_Clause : Node_Id) return Node_Id 11310 is 11311 Par : constant Node_Id := Parent (Var); 11312 Typ : constant Entity_Id := Etype (Var); 11313 11314 Init_Proc : Entity_Id; 11315 -- Initialization procedure for Typ 11316 11317 function Find_Init_Call_In_List (From : Node_Id) return Node_Id; 11318 -- Look for init call for Var starting at From and scanning the 11319 -- enclosing list until Rep_Clause or the end of the list is reached. 11320 11321 ---------------------------- 11322 -- Find_Init_Call_In_List -- 11323 ---------------------------- 11324 11325 function Find_Init_Call_In_List (From : Node_Id) return Node_Id is 11326 Init_Call : Node_Id; 11327 11328 begin 11329 Init_Call := From; 11330 while Present (Init_Call) and then Init_Call /= Rep_Clause loop 11331 if Nkind (Init_Call) = N_Procedure_Call_Statement 11332 and then Is_Entity_Name (Name (Init_Call)) 11333 and then Entity (Name (Init_Call)) = Init_Proc 11334 then 11335 return Init_Call; 11336 end if; 11337 11338 Next (Init_Call); 11339 end loop; 11340 11341 return Empty; 11342 end Find_Init_Call_In_List; 11343 11344 Init_Call : Node_Id; 11345 11346 -- Start of processing for Find_Init_Call 11347 11348 begin 11349 if Present (Initialization_Statements (Var)) then 11350 Init_Call := Initialization_Statements (Var); 11351 Set_Initialization_Statements (Var, Empty); 11352 11353 elsif not Has_Non_Null_Base_Init_Proc (Typ) then 11354 11355 -- No init proc for the type, so obviously no call to be found 11356 11357 return Empty; 11358 11359 else 11360 -- We might be able to handle other cases below by just properly 11361 -- setting Initialization_Statements at the point where the init proc 11362 -- call is generated??? 11363 11364 Init_Proc := Base_Init_Proc (Typ); 11365 11366 -- First scan the list containing the declaration of Var 11367 11368 Init_Call := Find_Init_Call_In_List (From => Next (Par)); 11369 11370 -- If not found, also look on Var's freeze actions list, if any, 11371 -- since the init call may have been moved there (case of an address 11372 -- clause applying to Var). 11373 11374 if No (Init_Call) and then Present (Freeze_Node (Var)) then 11375 Init_Call := 11376 Find_Init_Call_In_List (First (Actions (Freeze_Node (Var)))); 11377 end if; 11378 11379 -- If the initialization call has actuals that use the secondary 11380 -- stack, the call may have been wrapped into a temporary block, in 11381 -- which case the block itself has to be removed. 11382 11383 if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then 11384 declare 11385 Blk : constant Node_Id := Next (Par); 11386 begin 11387 if Present 11388 (Find_Init_Call_In_List 11389 (First (Statements (Handled_Statement_Sequence (Blk))))) 11390 then 11391 Init_Call := Blk; 11392 end if; 11393 end; 11394 end if; 11395 end if; 11396 11397 if Present (Init_Call) then 11398 Remove (Init_Call); 11399 end if; 11400 return Init_Call; 11401 end Remove_Init_Call; 11402 11403 ------------------------- 11404 -- Remove_Side_Effects -- 11405 ------------------------- 11406 11407 procedure Remove_Side_Effects 11408 (Exp : Node_Id; 11409 Name_Req : Boolean := False; 11410 Renaming_Req : Boolean := False; 11411 Variable_Ref : Boolean := False; 11412 Related_Id : Entity_Id := Empty; 11413 Is_Low_Bound : Boolean := False; 11414 Is_High_Bound : Boolean := False; 11415 Check_Side_Effects : Boolean := True) 11416 is 11417 function Build_Temporary 11418 (Loc : Source_Ptr; 11419 Id : Character; 11420 Related_Nod : Node_Id := Empty) return Entity_Id; 11421 -- Create an external symbol of the form xxx_FIRST/_LAST if Related_Nod 11422 -- is present (xxx is taken from the Chars field of Related_Nod), 11423 -- otherwise it generates an internal temporary. The created temporary 11424 -- entity is marked as internal. 11425 11426 function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean; 11427 -- Computes whether a side effect is possible in SPARK, which should 11428 -- be handled by removing it from the expression for GNATprove. Note 11429 -- that other side effects related to volatile variables are handled 11430 -- separately. 11431 11432 --------------------- 11433 -- Build_Temporary -- 11434 --------------------- 11435 11436 function Build_Temporary 11437 (Loc : Source_Ptr; 11438 Id : Character; 11439 Related_Nod : Node_Id := Empty) return Entity_Id 11440 is 11441 Temp_Id : Entity_Id; 11442 Temp_Nam : Name_Id; 11443 11444 begin 11445 -- The context requires an external symbol 11446 11447 if Present (Related_Id) then 11448 if Is_Low_Bound then 11449 Temp_Nam := New_External_Name (Chars (Related_Id), "_FIRST"); 11450 else pragma Assert (Is_High_Bound); 11451 Temp_Nam := New_External_Name (Chars (Related_Id), "_LAST"); 11452 end if; 11453 11454 Temp_Id := Make_Defining_Identifier (Loc, Temp_Nam); 11455 11456 -- Otherwise generate an internal temporary 11457 11458 else 11459 Temp_Id := Make_Temporary (Loc, Id, Related_Nod); 11460 end if; 11461 11462 Set_Is_Internal (Temp_Id); 11463 11464 return Temp_Id; 11465 end Build_Temporary; 11466 11467 ----------------------------------- 11468 -- Possible_Side_Effect_In_SPARK -- 11469 ----------------------------------- 11470 11471 function Possible_Side_Effect_In_SPARK (Exp : Node_Id) return Boolean is 11472 begin 11473 -- Side-effect removal in SPARK should only occur when not inside a 11474 -- generic and not doing a preanalysis, inside an object renaming or 11475 -- a type declaration or a for-loop iteration scheme. 11476 11477 return not Inside_A_Generic 11478 and then Full_Analysis 11479 and then Nkind (Enclosing_Declaration (Exp)) in 11480 N_Full_Type_Declaration 11481 | N_Iterator_Specification 11482 | N_Loop_Parameter_Specification 11483 | N_Object_Renaming_Declaration 11484 | N_Subtype_Declaration; 11485 end Possible_Side_Effect_In_SPARK; 11486 11487 -- Local variables 11488 11489 Loc : constant Source_Ptr := Sloc (Exp); 11490 Exp_Type : constant Entity_Id := Etype (Exp); 11491 Svg_Suppress : constant Suppress_Record := Scope_Suppress; 11492 Def_Id : Entity_Id; 11493 E : Node_Id; 11494 New_Exp : Node_Id; 11495 Ptr_Typ_Decl : Node_Id; 11496 Ref_Type : Entity_Id; 11497 Res : Node_Id; 11498 11499 -- Start of processing for Remove_Side_Effects 11500 11501 begin 11502 -- Handle cases in which there is nothing to do. In GNATprove mode, 11503 -- removal of side effects is useful for the light expansion of 11504 -- renamings. 11505 11506 if not Expander_Active 11507 and then not 11508 (GNATprove_Mode and then Possible_Side_Effect_In_SPARK (Exp)) 11509 then 11510 return; 11511 11512 -- Cannot generate temporaries if the invocation to remove side effects 11513 -- was issued too early and the type of the expression is not resolved 11514 -- (this happens because routines Duplicate_Subexpr_XX implicitly invoke 11515 -- Remove_Side_Effects). 11516 11517 elsif No (Exp_Type) 11518 or else Ekind (Exp_Type) = E_Access_Attribute_Type 11519 then 11520 return; 11521 11522 -- Nothing to do if prior expansion determined that a function call does 11523 -- not require side effect removal. 11524 11525 elsif Nkind (Exp) = N_Function_Call 11526 and then No_Side_Effect_Removal (Exp) 11527 then 11528 return; 11529 11530 -- No action needed for side-effect free expressions 11531 11532 elsif Check_Side_Effects 11533 and then Side_Effect_Free (Exp, Name_Req, Variable_Ref) 11534 then 11535 return; 11536 11537 -- Generating C code we cannot remove side effect of function returning 11538 -- class-wide types since there is no secondary stack (required to use 11539 -- 'reference). 11540 11541 elsif Modify_Tree_For_C 11542 and then Nkind (Exp) = N_Function_Call 11543 and then Is_Class_Wide_Type (Etype (Exp)) 11544 then 11545 return; 11546 end if; 11547 11548 -- The remaining processing is done with all checks suppressed 11549 11550 -- Note: from now on, don't use return statements, instead do a goto 11551 -- Leave, to ensure that we properly restore Scope_Suppress.Suppress. 11552 11553 Scope_Suppress.Suppress := (others => True); 11554 11555 -- If this is a side-effect free attribute reference whose expressions 11556 -- are also side-effect free and whose prefix is not a name, remove the 11557 -- side effects of the prefix. A copy of the prefix is required in this 11558 -- case and it is better not to make an additional one for the attribute 11559 -- itself, because the return type of many of them is universal integer, 11560 -- which is a very large type for a temporary. 11561 11562 if Nkind (Exp) = N_Attribute_Reference 11563 and then Side_Effect_Free_Attribute (Attribute_Name (Exp)) 11564 and then Side_Effect_Free (Expressions (Exp), Name_Req, Variable_Ref) 11565 and then not Is_Name_Reference (Prefix (Exp)) 11566 then 11567 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref); 11568 goto Leave; 11569 11570 -- If this is an elementary or a small not-by-reference record type, and 11571 -- we need to capture the value, just make a constant; this is cheap and 11572 -- objects of both kinds of types can be bit aligned, so it might not be 11573 -- possible to generate a reference to them. Likewise if this is not a 11574 -- name reference, except for a type conversion, because we would enter 11575 -- an infinite recursion with Checks.Apply_Predicate_Check if the target 11576 -- type has predicates (and type conversions need a specific treatment 11577 -- anyway, see below). Also do it if we have a volatile reference and 11578 -- Name_Req is not set (see comments for Side_Effect_Free). 11579 11580 elsif (Is_Elementary_Type (Exp_Type) 11581 or else (Is_Record_Type (Exp_Type) 11582 and then Known_Static_RM_Size (Exp_Type) 11583 and then RM_Size (Exp_Type) <= System_Max_Integer_Size 11584 and then not Has_Discriminants (Exp_Type) 11585 and then not Is_By_Reference_Type (Exp_Type))) 11586 and then (Variable_Ref 11587 or else (not Is_Name_Reference (Exp) 11588 and then Nkind (Exp) /= N_Type_Conversion) 11589 or else (not Name_Req 11590 and then Is_Volatile_Reference (Exp))) 11591 then 11592 Def_Id := Build_Temporary (Loc, 'R', Exp); 11593 Set_Etype (Def_Id, Exp_Type); 11594 Res := New_Occurrence_Of (Def_Id, Loc); 11595 11596 -- If the expression is a packed reference, it must be reanalyzed and 11597 -- expanded, depending on context. This is the case for actuals where 11598 -- a constraint check may capture the actual before expansion of the 11599 -- call is complete. 11600 11601 if Nkind (Exp) = N_Indexed_Component 11602 and then Is_Packed (Etype (Prefix (Exp))) 11603 then 11604 Set_Analyzed (Exp, False); 11605 Set_Analyzed (Prefix (Exp), False); 11606 end if; 11607 11608 -- Generate: 11609 -- Rnn : Exp_Type renames Expr; 11610 11611 -- In GNATprove mode, we prefer to use renamings for intermediate 11612 -- variables to definition of constants, due to the implicit move 11613 -- operation that such a constant definition causes as part of the 11614 -- support in GNATprove for ownership pointers. Hence, we generate 11615 -- a renaming for a reference to an object of a nonscalar type. 11616 11617 if Renaming_Req 11618 or else (GNATprove_Mode 11619 and then Is_Object_Reference (Exp) 11620 and then not Is_Scalar_Type (Exp_Type)) 11621 then 11622 E := 11623 Make_Object_Renaming_Declaration (Loc, 11624 Defining_Identifier => Def_Id, 11625 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11626 Name => Relocate_Node (Exp)); 11627 11628 -- Generate: 11629 -- Rnn : constant Exp_Type := Expr; 11630 11631 else 11632 E := 11633 Make_Object_Declaration (Loc, 11634 Defining_Identifier => Def_Id, 11635 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11636 Constant_Present => True, 11637 Expression => Relocate_Node (Exp)); 11638 11639 Set_Assignment_OK (E); 11640 end if; 11641 11642 Insert_Action (Exp, E); 11643 11644 -- If the expression has the form v.all then we can just capture the 11645 -- pointer, and then do an explicit dereference on the result, but 11646 -- this is not right if this is a volatile reference. 11647 11648 elsif Nkind (Exp) = N_Explicit_Dereference 11649 and then not Is_Volatile_Reference (Exp) 11650 then 11651 Def_Id := Build_Temporary (Loc, 'R', Exp); 11652 Res := 11653 Make_Explicit_Dereference (Loc, New_Occurrence_Of (Def_Id, Loc)); 11654 11655 Insert_Action (Exp, 11656 Make_Object_Declaration (Loc, 11657 Defining_Identifier => Def_Id, 11658 Object_Definition => 11659 New_Occurrence_Of (Etype (Prefix (Exp)), Loc), 11660 Constant_Present => True, 11661 Expression => Relocate_Node (Prefix (Exp)))); 11662 11663 -- Similar processing for an unchecked conversion of an expression of 11664 -- the form v.all, where we want the same kind of treatment. 11665 11666 elsif Nkind (Exp) = N_Unchecked_Type_Conversion 11667 and then Nkind (Expression (Exp)) = N_Explicit_Dereference 11668 then 11669 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref); 11670 goto Leave; 11671 11672 -- If this is a type conversion, leave the type conversion and remove 11673 -- side effects in the expression, unless it is of universal integer, 11674 -- which is a very large type for a temporary. This is important in 11675 -- several circumstances: for change of representations and also when 11676 -- this is a view conversion to a smaller object, where gigi can end 11677 -- up creating its own temporary of the wrong size. 11678 11679 elsif Nkind (Exp) = N_Type_Conversion 11680 and then Etype (Expression (Exp)) /= Universal_Integer 11681 then 11682 Remove_Side_Effects (Expression (Exp), Name_Req, Variable_Ref); 11683 11684 -- Generating C code the type conversion of an access to constrained 11685 -- array type into an access to unconstrained array type involves 11686 -- initializing a fat pointer and the expression must be free of 11687 -- side effects to safely compute its bounds. 11688 11689 if Modify_Tree_For_C 11690 and then Is_Access_Type (Etype (Exp)) 11691 and then Is_Array_Type (Designated_Type (Etype (Exp))) 11692 and then not Is_Constrained (Designated_Type (Etype (Exp))) 11693 then 11694 Def_Id := Build_Temporary (Loc, 'R', Exp); 11695 Set_Etype (Def_Id, Exp_Type); 11696 Res := New_Occurrence_Of (Def_Id, Loc); 11697 11698 Insert_Action (Exp, 11699 Make_Object_Declaration (Loc, 11700 Defining_Identifier => Def_Id, 11701 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11702 Constant_Present => True, 11703 Expression => Relocate_Node (Exp))); 11704 else 11705 goto Leave; 11706 end if; 11707 11708 -- If this is an unchecked conversion that Gigi can't handle, make 11709 -- a copy or a use a renaming to capture the value. 11710 11711 elsif Nkind (Exp) = N_Unchecked_Type_Conversion 11712 and then not Safe_Unchecked_Type_Conversion (Exp) 11713 then 11714 if CW_Or_Has_Controlled_Part (Exp_Type) then 11715 11716 -- Use a renaming to capture the expression, rather than create 11717 -- a controlled temporary. 11718 11719 Def_Id := Build_Temporary (Loc, 'R', Exp); 11720 Res := New_Occurrence_Of (Def_Id, Loc); 11721 11722 Insert_Action (Exp, 11723 Make_Object_Renaming_Declaration (Loc, 11724 Defining_Identifier => Def_Id, 11725 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11726 Name => Relocate_Node (Exp))); 11727 11728 else 11729 Def_Id := Build_Temporary (Loc, 'R', Exp); 11730 Set_Etype (Def_Id, Exp_Type); 11731 Res := New_Occurrence_Of (Def_Id, Loc); 11732 11733 E := 11734 Make_Object_Declaration (Loc, 11735 Defining_Identifier => Def_Id, 11736 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11737 Constant_Present => not Is_Variable (Exp), 11738 Expression => Relocate_Node (Exp)); 11739 11740 Set_Assignment_OK (E); 11741 Insert_Action (Exp, E); 11742 end if; 11743 11744 -- If this is a packed array component or a selected component with a 11745 -- nonstandard representation, we cannot generate a reference because 11746 -- the component may be unaligned, so we must use a renaming and this 11747 -- renaming is handled by the front end, as the back end may balk at 11748 -- the nonstandard representation (see Evaluation_Required in Exp_Ch8). 11749 11750 elsif Nkind (Exp) in N_Indexed_Component | N_Selected_Component 11751 and then Has_Non_Standard_Rep (Etype (Prefix (Exp))) 11752 then 11753 Def_Id := Build_Temporary (Loc, 'R', Exp); 11754 Res := New_Occurrence_Of (Def_Id, Loc); 11755 11756 Insert_Action (Exp, 11757 Make_Object_Renaming_Declaration (Loc, 11758 Defining_Identifier => Def_Id, 11759 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11760 Name => Relocate_Node (Exp))); 11761 11762 -- For an expression that denotes a name, we can use a renaming scheme. 11763 -- This is needed for correctness in the case of a volatile object of 11764 -- a nonvolatile type because the Make_Reference call of the "default" 11765 -- approach would generate an illegal access value (an access value 11766 -- cannot designate such an object - see Analyze_Reference). 11767 11768 elsif Is_Name_Reference (Exp) 11769 11770 -- We skip using this scheme if we have an object of a volatile 11771 -- type and we do not have Name_Req set true (see comments for 11772 -- Side_Effect_Free). 11773 11774 and then (Name_Req or else not Treat_As_Volatile (Exp_Type)) 11775 then 11776 Def_Id := Build_Temporary (Loc, 'R', Exp); 11777 Res := New_Occurrence_Of (Def_Id, Loc); 11778 11779 Insert_Action (Exp, 11780 Make_Object_Renaming_Declaration (Loc, 11781 Defining_Identifier => Def_Id, 11782 Subtype_Mark => New_Occurrence_Of (Exp_Type, Loc), 11783 Name => Relocate_Node (Exp))); 11784 11785 -- Avoid generating a variable-sized temporary, by generating the 11786 -- reference just for the function call. The transformation could be 11787 -- refined to apply only when the array component is constrained by a 11788 -- discriminant??? 11789 11790 elsif Nkind (Exp) = N_Selected_Component 11791 and then Nkind (Prefix (Exp)) = N_Function_Call 11792 and then Is_Array_Type (Exp_Type) 11793 then 11794 Remove_Side_Effects (Prefix (Exp), Name_Req, Variable_Ref); 11795 goto Leave; 11796 11797 -- Otherwise we generate a reference to the expression 11798 11799 else 11800 -- When generating C code we cannot consider side effect free object 11801 -- declarations that have discriminants and are initialized by means 11802 -- of a function call since on this target there is no secondary 11803 -- stack to store the return value and the expander may generate an 11804 -- extra call to the function to compute the discriminant value. In 11805 -- addition, for targets that have secondary stack, the expansion of 11806 -- functions with side effects involves the generation of an access 11807 -- type to capture the return value stored in the secondary stack; 11808 -- by contrast when generating C code such expansion generates an 11809 -- internal object declaration (no access type involved) which must 11810 -- be identified here to avoid entering into a never-ending loop 11811 -- generating internal object declarations. 11812 11813 if Modify_Tree_For_C 11814 and then Nkind (Parent (Exp)) = N_Object_Declaration 11815 and then 11816 (Nkind (Exp) /= N_Function_Call 11817 or else not Has_Discriminants (Exp_Type) 11818 or else Is_Internal_Name 11819 (Chars (Defining_Identifier (Parent (Exp))))) 11820 then 11821 goto Leave; 11822 end if; 11823 11824 -- Special processing for function calls that return a limited type. 11825 -- We need to build a declaration that will enable build-in-place 11826 -- expansion of the call. This is not done if the context is already 11827 -- an object declaration, to prevent infinite recursion. 11828 11829 -- This is relevant only in Ada 2005 mode. In Ada 95 programs we have 11830 -- to accommodate functions returning limited objects by reference. 11831 11832 if Ada_Version >= Ada_2005 11833 and then Nkind (Exp) = N_Function_Call 11834 and then Is_Limited_View (Etype (Exp)) 11835 and then Nkind (Parent (Exp)) /= N_Object_Declaration 11836 then 11837 declare 11838 Obj : constant Entity_Id := Make_Temporary (Loc, 'F', Exp); 11839 Decl : Node_Id; 11840 11841 begin 11842 Decl := 11843 Make_Object_Declaration (Loc, 11844 Defining_Identifier => Obj, 11845 Object_Definition => New_Occurrence_Of (Exp_Type, Loc), 11846 Expression => Relocate_Node (Exp)); 11847 11848 Insert_Action (Exp, Decl); 11849 Set_Etype (Obj, Exp_Type); 11850 Rewrite (Exp, New_Occurrence_Of (Obj, Loc)); 11851 goto Leave; 11852 end; 11853 end if; 11854 11855 Def_Id := Build_Temporary (Loc, 'R', Exp); 11856 11857 -- The regular expansion of functions with side effects involves the 11858 -- generation of an access type to capture the return value found on 11859 -- the secondary stack. Since SPARK (and why) cannot process access 11860 -- types, use a different approach which ignores the secondary stack 11861 -- and "copies" the returned object. 11862 -- When generating C code, no need for a 'reference since the 11863 -- secondary stack is not supported. 11864 11865 if GNATprove_Mode or Modify_Tree_For_C then 11866 Res := New_Occurrence_Of (Def_Id, Loc); 11867 Ref_Type := Exp_Type; 11868 11869 -- Regular expansion utilizing an access type and 'reference 11870 11871 else 11872 Res := 11873 Make_Explicit_Dereference (Loc, 11874 Prefix => New_Occurrence_Of (Def_Id, Loc)); 11875 11876 -- Generate: 11877 -- type Ann is access all <Exp_Type>; 11878 11879 Ref_Type := Make_Temporary (Loc, 'A'); 11880 11881 Ptr_Typ_Decl := 11882 Make_Full_Type_Declaration (Loc, 11883 Defining_Identifier => Ref_Type, 11884 Type_Definition => 11885 Make_Access_To_Object_Definition (Loc, 11886 All_Present => True, 11887 Subtype_Indication => 11888 New_Occurrence_Of (Exp_Type, Loc))); 11889 11890 Insert_Action (Exp, Ptr_Typ_Decl); 11891 end if; 11892 11893 E := Exp; 11894 if Nkind (E) = N_Explicit_Dereference then 11895 New_Exp := Relocate_Node (Prefix (E)); 11896 11897 else 11898 E := Relocate_Node (E); 11899 11900 -- Do not generate a 'reference in SPARK mode or C generation 11901 -- since the access type is not created in the first place. 11902 11903 if GNATprove_Mode or Modify_Tree_For_C then 11904 New_Exp := E; 11905 11906 -- Otherwise generate reference, marking the value as non-null 11907 -- since we know it cannot be null and we don't want a check. 11908 11909 else 11910 New_Exp := Make_Reference (Loc, E); 11911 Set_Is_Known_Non_Null (Def_Id); 11912 end if; 11913 end if; 11914 11915 if Is_Delayed_Aggregate (E) then 11916 11917 -- The expansion of nested aggregates is delayed until the 11918 -- enclosing aggregate is expanded. As aggregates are often 11919 -- qualified, the predicate applies to qualified expressions as 11920 -- well, indicating that the enclosing aggregate has not been 11921 -- expanded yet. At this point the aggregate is part of a 11922 -- stand-alone declaration, and must be fully expanded. 11923 11924 if Nkind (E) = N_Qualified_Expression then 11925 Set_Expansion_Delayed (Expression (E), False); 11926 Set_Analyzed (Expression (E), False); 11927 else 11928 Set_Expansion_Delayed (E, False); 11929 end if; 11930 11931 Set_Analyzed (E, False); 11932 end if; 11933 11934 -- Generating C code of object declarations that have discriminants 11935 -- and are initialized by means of a function call we propagate the 11936 -- discriminants of the parent type to the internally built object. 11937 -- This is needed to avoid generating an extra call to the called 11938 -- function. 11939 11940 -- For example, if we generate here the following declaration, it 11941 -- will be expanded later adding an extra call to evaluate the value 11942 -- of the discriminant (needed to compute the size of the object). 11943 -- 11944 -- type Rec (D : Integer) is ... 11945 -- Obj : constant Rec := SomeFunc; 11946 11947 if Modify_Tree_For_C 11948 and then Nkind (Parent (Exp)) = N_Object_Declaration 11949 and then Has_Discriminants (Exp_Type) 11950 and then Nkind (Exp) = N_Function_Call 11951 then 11952 Insert_Action (Exp, 11953 Make_Object_Declaration (Loc, 11954 Defining_Identifier => Def_Id, 11955 Object_Definition => New_Copy_Tree 11956 (Object_Definition (Parent (Exp))), 11957 Constant_Present => True, 11958 Expression => New_Exp)); 11959 else 11960 Insert_Action (Exp, 11961 Make_Object_Declaration (Loc, 11962 Defining_Identifier => Def_Id, 11963 Object_Definition => New_Occurrence_Of (Ref_Type, Loc), 11964 Constant_Present => True, 11965 Expression => New_Exp)); 11966 end if; 11967 end if; 11968 11969 -- Preserve the Assignment_OK flag in all copies, since at least one 11970 -- copy may be used in a context where this flag must be set (otherwise 11971 -- why would the flag be set in the first place). 11972 11973 Set_Assignment_OK (Res, Assignment_OK (Exp)); 11974 11975 -- Preserve the Do_Range_Check flag in all copies 11976 11977 Set_Do_Range_Check (Res, Do_Range_Check (Exp)); 11978 11979 -- Finally rewrite the original expression and we are done 11980 11981 Rewrite (Exp, Res); 11982 Analyze_And_Resolve (Exp, Exp_Type); 11983 11984 <<Leave>> 11985 Scope_Suppress := Svg_Suppress; 11986 end Remove_Side_Effects; 11987 11988 ------------------------ 11989 -- Replace_References -- 11990 ------------------------ 11991 11992 procedure Replace_References 11993 (Expr : Node_Id; 11994 Par_Typ : Entity_Id; 11995 Deriv_Typ : Entity_Id; 11996 Par_Obj : Entity_Id := Empty; 11997 Deriv_Obj : Entity_Id := Empty) 11998 is 11999 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean; 12000 -- Determine whether node Ref denotes some component of Deriv_Obj 12001 12002 function Replace_Ref (Ref : Node_Id) return Traverse_Result; 12003 -- Substitute a reference to an entity with the corresponding value 12004 -- stored in table Type_Map. 12005 12006 function Type_Of_Formal 12007 (Call : Node_Id; 12008 Actual : Node_Id) return Entity_Id; 12009 -- Find the type of the formal parameter which corresponds to actual 12010 -- parameter Actual in subprogram call Call. 12011 12012 ---------------------- 12013 -- Is_Deriv_Obj_Ref -- 12014 ---------------------- 12015 12016 function Is_Deriv_Obj_Ref (Ref : Node_Id) return Boolean is 12017 Par : constant Node_Id := Parent (Ref); 12018 12019 begin 12020 -- Detect the folowing selected component form: 12021 12022 -- Deriv_Obj.(something) 12023 12024 return 12025 Nkind (Par) = N_Selected_Component 12026 and then Is_Entity_Name (Prefix (Par)) 12027 and then Entity (Prefix (Par)) = Deriv_Obj; 12028 end Is_Deriv_Obj_Ref; 12029 12030 ----------------- 12031 -- Replace_Ref -- 12032 ----------------- 12033 12034 function Replace_Ref (Ref : Node_Id) return Traverse_Result is 12035 procedure Remove_Controlling_Arguments (From_Arg : Node_Id); 12036 -- Reset the Controlling_Argument of all function calls that 12037 -- encapsulate node From_Arg. 12038 12039 ---------------------------------- 12040 -- Remove_Controlling_Arguments -- 12041 ---------------------------------- 12042 12043 procedure Remove_Controlling_Arguments (From_Arg : Node_Id) is 12044 Par : Node_Id; 12045 12046 begin 12047 Par := From_Arg; 12048 while Present (Par) loop 12049 if Nkind (Par) = N_Function_Call 12050 and then Present (Controlling_Argument (Par)) 12051 then 12052 Set_Controlling_Argument (Par, Empty); 12053 12054 -- Prevent the search from going too far 12055 12056 elsif Is_Body_Or_Package_Declaration (Par) then 12057 exit; 12058 end if; 12059 12060 Par := Parent (Par); 12061 end loop; 12062 end Remove_Controlling_Arguments; 12063 12064 -- Local variables 12065 12066 Context : constant Node_Id := Parent (Ref); 12067 Loc : constant Source_Ptr := Sloc (Ref); 12068 Ref_Id : Entity_Id; 12069 Result : Traverse_Result; 12070 12071 New_Ref : Node_Id; 12072 -- The new reference which is intended to substitute the old one 12073 12074 Old_Ref : Node_Id; 12075 -- The reference designated for replacement. In certain cases this 12076 -- may be a node other than Ref. 12077 12078 Val : Node_Or_Entity_Id; 12079 -- The corresponding value of Ref from the type map 12080 12081 -- Start of processing for Replace_Ref 12082 12083 begin 12084 -- Assume that the input reference is to be replaced and that the 12085 -- traversal should examine the children of the reference. 12086 12087 Old_Ref := Ref; 12088 Result := OK; 12089 12090 -- The input denotes a meaningful reference 12091 12092 if Nkind (Ref) in N_Has_Entity and then Present (Entity (Ref)) then 12093 Ref_Id := Entity (Ref); 12094 Val := Type_Map.Get (Ref_Id); 12095 12096 -- The reference has a corresponding value in the type map, a 12097 -- substitution is possible. 12098 12099 if Present (Val) then 12100 12101 -- The reference denotes a discriminant 12102 12103 if Ekind (Ref_Id) = E_Discriminant then 12104 if Nkind (Val) in N_Entity then 12105 12106 -- The value denotes another discriminant. Replace as 12107 -- follows: 12108 12109 -- _object.Discr -> _object.Val 12110 12111 if Ekind (Val) = E_Discriminant then 12112 New_Ref := New_Occurrence_Of (Val, Loc); 12113 12114 -- Otherwise the value denotes the entity of a name which 12115 -- constraints the discriminant. Replace as follows: 12116 12117 -- _object.Discr -> Val 12118 12119 else 12120 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref)); 12121 12122 New_Ref := New_Occurrence_Of (Val, Loc); 12123 Old_Ref := Parent (Old_Ref); 12124 end if; 12125 12126 -- Otherwise the value denotes an arbitrary expression which 12127 -- constraints the discriminant. Replace as follows: 12128 12129 -- _object.Discr -> Val 12130 12131 else 12132 pragma Assert (Is_Deriv_Obj_Ref (Old_Ref)); 12133 12134 New_Ref := New_Copy_Tree (Val); 12135 Old_Ref := Parent (Old_Ref); 12136 end if; 12137 12138 -- Otherwise the reference denotes a primitive. Replace as 12139 -- follows: 12140 12141 -- Primitive -> Val 12142 12143 else 12144 pragma Assert (Nkind (Val) in N_Entity); 12145 New_Ref := New_Occurrence_Of (Val, Loc); 12146 end if; 12147 12148 -- The reference mentions the _object parameter of the parent 12149 -- type's DIC or type invariant procedure. Replace as follows: 12150 12151 -- _object -> _object 12152 12153 elsif Present (Par_Obj) 12154 and then Present (Deriv_Obj) 12155 and then Ref_Id = Par_Obj 12156 then 12157 New_Ref := New_Occurrence_Of (Deriv_Obj, Loc); 12158 12159 -- The type of the _object parameter is class-wide when the 12160 -- expression comes from an assertion pragma that applies to 12161 -- an abstract parent type or an interface. The class-wide type 12162 -- facilitates the preanalysis of the expression by treating 12163 -- calls to abstract primitives that mention the current 12164 -- instance of the type as dispatching. Once the calls are 12165 -- remapped to invoke overriding or inherited primitives, the 12166 -- calls no longer need to be dispatching. Examine all function 12167 -- calls that encapsulate the _object parameter and reset their 12168 -- Controlling_Argument attribute. 12169 12170 if Is_Class_Wide_Type (Etype (Par_Obj)) 12171 and then Is_Abstract_Type (Root_Type (Etype (Par_Obj))) 12172 then 12173 Remove_Controlling_Arguments (Old_Ref); 12174 end if; 12175 12176 -- The reference to _object acts as an actual parameter in a 12177 -- subprogram call which may be invoking a primitive of the 12178 -- parent type: 12179 12180 -- Primitive (... _object ...); 12181 12182 -- The parent type primitive may not be overridden nor 12183 -- inherited when it is declared after the derived type 12184 -- definition: 12185 12186 -- type Parent is tagged private; 12187 -- type Child is new Parent with private; 12188 -- procedure Primitive (Obj : Parent); 12189 12190 -- In this scenario the _object parameter is converted to the 12191 -- parent type. Due to complications with partial/full views 12192 -- and view swaps, the parent type is taken from the formal 12193 -- parameter of the subprogram being called. 12194 12195 if Nkind (Context) in N_Subprogram_Call 12196 and then No (Type_Map.Get (Entity (Name (Context)))) 12197 then 12198 New_Ref := 12199 Convert_To (Type_Of_Formal (Context, Old_Ref), New_Ref); 12200 12201 -- Do not process the generated type conversion because 12202 -- both the parent type and the derived type are in the 12203 -- Type_Map table. This will clobber the type conversion 12204 -- by resetting its subtype mark. 12205 12206 Result := Skip; 12207 end if; 12208 12209 -- Otherwise there is nothing to replace 12210 12211 else 12212 New_Ref := Empty; 12213 end if; 12214 12215 if Present (New_Ref) then 12216 Rewrite (Old_Ref, New_Ref); 12217 12218 -- Update the return type when the context of the reference 12219 -- acts as the name of a function call. Note that the update 12220 -- should not be performed when the reference appears as an 12221 -- actual in the call. 12222 12223 if Nkind (Context) = N_Function_Call 12224 and then Name (Context) = Old_Ref 12225 then 12226 Set_Etype (Context, Etype (Val)); 12227 end if; 12228 end if; 12229 end if; 12230 12231 -- Reanalyze the reference due to potential replacements 12232 12233 if Nkind (Old_Ref) in N_Has_Etype then 12234 Set_Analyzed (Old_Ref, False); 12235 end if; 12236 12237 return Result; 12238 end Replace_Ref; 12239 12240 procedure Replace_Refs is new Traverse_Proc (Replace_Ref); 12241 12242 -------------------- 12243 -- Type_Of_Formal -- 12244 -------------------- 12245 12246 function Type_Of_Formal 12247 (Call : Node_Id; 12248 Actual : Node_Id) return Entity_Id 12249 is 12250 A : Node_Id; 12251 F : Entity_Id; 12252 12253 begin 12254 -- Examine the list of actual and formal parameters in parallel 12255 12256 A := First (Parameter_Associations (Call)); 12257 F := First_Formal (Entity (Name (Call))); 12258 while Present (A) and then Present (F) loop 12259 if A = Actual then 12260 return Etype (F); 12261 end if; 12262 12263 Next (A); 12264 Next_Formal (F); 12265 end loop; 12266 12267 -- The actual parameter must always have a corresponding formal 12268 12269 pragma Assert (False); 12270 12271 return Empty; 12272 end Type_Of_Formal; 12273 12274 -- Start of processing for Replace_References 12275 12276 begin 12277 -- Map the attributes of the parent type to the proper corresponding 12278 -- attributes of the derived type. 12279 12280 Map_Types 12281 (Parent_Type => Par_Typ, 12282 Derived_Type => Deriv_Typ); 12283 12284 -- Inspect the input expression and perform substitutions where 12285 -- necessary. 12286 12287 Replace_Refs (Expr); 12288 end Replace_References; 12289 12290 ----------------------------- 12291 -- Replace_Type_References -- 12292 ----------------------------- 12293 12294 procedure Replace_Type_References 12295 (Expr : Node_Id; 12296 Typ : Entity_Id; 12297 Obj_Id : Entity_Id) 12298 is 12299 procedure Replace_Type_Ref (N : Node_Id); 12300 -- Substitute a single reference of the current instance of type Typ 12301 -- with a reference to Obj_Id. 12302 12303 ---------------------- 12304 -- Replace_Type_Ref -- 12305 ---------------------- 12306 12307 procedure Replace_Type_Ref (N : Node_Id) is 12308 begin 12309 -- Decorate the reference to Typ even though it may be rewritten 12310 -- further down. This is done so that routines which examine 12311 -- properties of the Original_Node have some semantic information. 12312 12313 if Nkind (N) = N_Identifier then 12314 Set_Entity (N, Typ); 12315 Set_Etype (N, Typ); 12316 12317 elsif Nkind (N) = N_Selected_Component then 12318 Analyze (Prefix (N)); 12319 Set_Entity (Selector_Name (N), Typ); 12320 Set_Etype (Selector_Name (N), Typ); 12321 end if; 12322 12323 -- Perform the following substitution: 12324 12325 -- Typ --> _object 12326 12327 Rewrite (N, New_Occurrence_Of (Obj_Id, Sloc (N))); 12328 Set_Comes_From_Source (N, True); 12329 end Replace_Type_Ref; 12330 12331 procedure Replace_Type_Refs is 12332 new Replace_Type_References_Generic (Replace_Type_Ref); 12333 12334 -- Start of processing for Replace_Type_References 12335 12336 begin 12337 Replace_Type_Refs (Expr, Typ); 12338 end Replace_Type_References; 12339 12340 --------------------------- 12341 -- Represented_As_Scalar -- 12342 --------------------------- 12343 12344 function Represented_As_Scalar (T : Entity_Id) return Boolean is 12345 UT : constant Entity_Id := Underlying_Type (T); 12346 begin 12347 return Is_Scalar_Type (UT) 12348 or else (Is_Bit_Packed_Array (UT) 12349 and then Is_Scalar_Type (Packed_Array_Impl_Type (UT))); 12350 end Represented_As_Scalar; 12351 12352 ------------------------------ 12353 -- Requires_Cleanup_Actions -- 12354 ------------------------------ 12355 12356 function Requires_Cleanup_Actions 12357 (N : Node_Id; 12358 Lib_Level : Boolean) return Boolean 12359 is 12360 At_Lib_Level : constant Boolean := 12361 Lib_Level 12362 and then Nkind (N) in N_Package_Body | N_Package_Specification; 12363 -- N is at the library level if the top-most context is a package and 12364 -- the path taken to reach N does not include nonpackage constructs. 12365 12366 begin 12367 case Nkind (N) is 12368 when N_Accept_Statement 12369 | N_Block_Statement 12370 | N_Entry_Body 12371 | N_Package_Body 12372 | N_Protected_Body 12373 | N_Subprogram_Body 12374 | N_Task_Body 12375 => 12376 return 12377 Requires_Cleanup_Actions 12378 (L => Declarations (N), 12379 Lib_Level => At_Lib_Level, 12380 Nested_Constructs => True) 12381 or else 12382 (Present (Handled_Statement_Sequence (N)) 12383 and then 12384 Requires_Cleanup_Actions 12385 (L => 12386 Statements (Handled_Statement_Sequence (N)), 12387 Lib_Level => At_Lib_Level, 12388 Nested_Constructs => True)); 12389 12390 -- Extended return statements are the same as the above, except that 12391 -- there is no Declarations field. We do not want to clean up the 12392 -- Return_Object_Declarations. 12393 12394 when N_Extended_Return_Statement => 12395 return 12396 Present (Handled_Statement_Sequence (N)) 12397 and then Requires_Cleanup_Actions 12398 (L => 12399 Statements (Handled_Statement_Sequence (N)), 12400 Lib_Level => At_Lib_Level, 12401 Nested_Constructs => True); 12402 12403 when N_Package_Specification => 12404 return 12405 Requires_Cleanup_Actions 12406 (L => Visible_Declarations (N), 12407 Lib_Level => At_Lib_Level, 12408 Nested_Constructs => True) 12409 or else 12410 Requires_Cleanup_Actions 12411 (L => Private_Declarations (N), 12412 Lib_Level => At_Lib_Level, 12413 Nested_Constructs => True); 12414 12415 when others => 12416 raise Program_Error; 12417 end case; 12418 end Requires_Cleanup_Actions; 12419 12420 ------------------------------ 12421 -- Requires_Cleanup_Actions -- 12422 ------------------------------ 12423 12424 function Requires_Cleanup_Actions 12425 (L : List_Id; 12426 Lib_Level : Boolean; 12427 Nested_Constructs : Boolean) return Boolean 12428 is 12429 Decl : Node_Id; 12430 Expr : Node_Id; 12431 Obj_Id : Entity_Id; 12432 Obj_Typ : Entity_Id; 12433 Pack_Id : Entity_Id; 12434 Typ : Entity_Id; 12435 12436 begin 12437 if No (L) or else Is_Empty_List (L) then 12438 return False; 12439 end if; 12440 12441 Decl := First (L); 12442 while Present (Decl) loop 12443 12444 -- Library-level tagged types 12445 12446 if Nkind (Decl) = N_Full_Type_Declaration then 12447 Typ := Defining_Identifier (Decl); 12448 12449 -- Ignored Ghost types do not need any cleanup actions because 12450 -- they will not appear in the final tree. 12451 12452 if Is_Ignored_Ghost_Entity (Typ) then 12453 null; 12454 12455 elsif Is_Tagged_Type (Typ) 12456 and then Is_Library_Level_Entity (Typ) 12457 and then Convention (Typ) = Convention_Ada 12458 and then Present (Access_Disp_Table (Typ)) 12459 and then RTE_Available (RE_Unregister_Tag) 12460 and then not Is_Abstract_Type (Typ) 12461 and then not No_Run_Time_Mode 12462 then 12463 return True; 12464 end if; 12465 12466 -- Regular object declarations 12467 12468 elsif Nkind (Decl) = N_Object_Declaration then 12469 Obj_Id := Defining_Identifier (Decl); 12470 Obj_Typ := Base_Type (Etype (Obj_Id)); 12471 Expr := Expression (Decl); 12472 12473 -- Bypass any form of processing for objects which have their 12474 -- finalization disabled. This applies only to objects at the 12475 -- library level. 12476 12477 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then 12478 null; 12479 12480 -- Finalization of transient objects are treated separately in 12481 -- order to handle sensitive cases. These include: 12482 12483 -- * Aggregate expansion 12484 -- * If, case, and expression with actions expansion 12485 -- * Transient scopes 12486 12487 -- If one of those contexts has marked the transient object as 12488 -- ignored, do not generate finalization actions for it. 12489 12490 elsif Is_Finalized_Transient (Obj_Id) 12491 or else Is_Ignored_Transient (Obj_Id) 12492 then 12493 null; 12494 12495 -- Ignored Ghost objects do not need any cleanup actions because 12496 -- they will not appear in the final tree. 12497 12498 elsif Is_Ignored_Ghost_Entity (Obj_Id) then 12499 null; 12500 12501 -- The object is of the form: 12502 -- Obj : [constant] Typ [:= Expr]; 12503 -- 12504 -- Do not process tag-to-class-wide conversions because they do 12505 -- not yield an object. Do not process the incomplete view of a 12506 -- deferred constant. Note that an object initialized by means 12507 -- of a build-in-place function call may appear as a deferred 12508 -- constant after expansion activities. These kinds of objects 12509 -- must be finalized. 12510 12511 elsif not Is_Imported (Obj_Id) 12512 and then Needs_Finalization (Obj_Typ) 12513 and then not Is_Tag_To_Class_Wide_Conversion (Obj_Id) 12514 and then not (Ekind (Obj_Id) = E_Constant 12515 and then not Has_Completion (Obj_Id) 12516 and then No (BIP_Initialization_Call (Obj_Id))) 12517 then 12518 return True; 12519 12520 -- The object is of the form: 12521 -- Obj : Access_Typ := Non_BIP_Function_Call'reference; 12522 -- 12523 -- Obj : Access_Typ := 12524 -- BIP_Function_Call (BIPalloc => 2, ...)'reference; 12525 12526 elsif Is_Access_Type (Obj_Typ) 12527 and then Needs_Finalization 12528 (Available_View (Designated_Type (Obj_Typ))) 12529 and then Present (Expr) 12530 and then 12531 (Is_Secondary_Stack_BIP_Func_Call (Expr) 12532 or else 12533 (Is_Non_BIP_Func_Call (Expr) 12534 and then not Is_Related_To_Func_Return (Obj_Id))) 12535 then 12536 return True; 12537 12538 -- Processing for "hook" objects generated for transient objects 12539 -- declared inside an Expression_With_Actions. 12540 12541 elsif Is_Access_Type (Obj_Typ) 12542 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) 12543 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) = 12544 N_Object_Declaration 12545 then 12546 return True; 12547 12548 -- Processing for intermediate results of if expressions where 12549 -- one of the alternatives uses a controlled function call. 12550 12551 elsif Is_Access_Type (Obj_Typ) 12552 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) 12553 and then Nkind (Status_Flag_Or_Transient_Decl (Obj_Id)) = 12554 N_Defining_Identifier 12555 and then Present (Expr) 12556 and then Nkind (Expr) = N_Null 12557 then 12558 return True; 12559 12560 -- Simple protected objects which use type System.Tasking. 12561 -- Protected_Objects.Protection to manage their locks should be 12562 -- treated as controlled since they require manual cleanup. 12563 12564 elsif Ekind (Obj_Id) = E_Variable 12565 and then (Is_Simple_Protected_Type (Obj_Typ) 12566 or else Has_Simple_Protected_Object (Obj_Typ)) 12567 then 12568 return True; 12569 end if; 12570 12571 -- Specific cases of object renamings 12572 12573 elsif Nkind (Decl) = N_Object_Renaming_Declaration then 12574 Obj_Id := Defining_Identifier (Decl); 12575 Obj_Typ := Base_Type (Etype (Obj_Id)); 12576 12577 -- Bypass any form of processing for objects which have their 12578 -- finalization disabled. This applies only to objects at the 12579 -- library level. 12580 12581 if Lib_Level and then Finalize_Storage_Only (Obj_Typ) then 12582 null; 12583 12584 -- Ignored Ghost object renamings do not need any cleanup actions 12585 -- because they will not appear in the final tree. 12586 12587 elsif Is_Ignored_Ghost_Entity (Obj_Id) then 12588 null; 12589 12590 -- Return object of a build-in-place function. This case is 12591 -- recognized and marked by the expansion of an extended return 12592 -- statement (see Expand_N_Extended_Return_Statement). 12593 12594 elsif Needs_Finalization (Obj_Typ) 12595 and then Is_Return_Object (Obj_Id) 12596 and then Present (Status_Flag_Or_Transient_Decl (Obj_Id)) 12597 then 12598 return True; 12599 12600 -- Detect a case where a source object has been initialized by 12601 -- a controlled function call or another object which was later 12602 -- rewritten as a class-wide conversion of Ada.Tags.Displace. 12603 12604 -- Obj1 : CW_Type := Src_Obj; 12605 -- Obj2 : CW_Type := Function_Call (...); 12606 12607 -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj)); 12608 -- Tmp : ... := Function_Call (...)'reference; 12609 -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp)); 12610 12611 elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then 12612 return True; 12613 end if; 12614 12615 -- Inspect the freeze node of an access-to-controlled type and look 12616 -- for a delayed finalization master. This case arises when the 12617 -- freeze actions are inserted at a later time than the expansion of 12618 -- the context. Since Build_Finalizer is never called on a single 12619 -- construct twice, the master will be ultimately left out and never 12620 -- finalized. This is also needed for freeze actions of designated 12621 -- types themselves, since in some cases the finalization master is 12622 -- associated with a designated type's freeze node rather than that 12623 -- of the access type (see handling for freeze actions in 12624 -- Build_Finalization_Master). 12625 12626 elsif Nkind (Decl) = N_Freeze_Entity 12627 and then Present (Actions (Decl)) 12628 then 12629 Typ := Entity (Decl); 12630 12631 -- Freeze nodes for ignored Ghost types do not need cleanup 12632 -- actions because they will never appear in the final tree. 12633 12634 if Is_Ignored_Ghost_Entity (Typ) then 12635 null; 12636 12637 elsif ((Is_Access_Object_Type (Typ) 12638 and then Needs_Finalization 12639 (Available_View (Designated_Type (Typ)))) 12640 or else (Is_Type (Typ) and then Needs_Finalization (Typ))) 12641 and then Requires_Cleanup_Actions 12642 (Actions (Decl), Lib_Level, Nested_Constructs) 12643 then 12644 return True; 12645 end if; 12646 12647 -- Nested package declarations 12648 12649 elsif Nested_Constructs 12650 and then Nkind (Decl) = N_Package_Declaration 12651 then 12652 Pack_Id := Defining_Entity (Decl); 12653 12654 -- Do not inspect an ignored Ghost package because all code found 12655 -- within will not appear in the final tree. 12656 12657 if Is_Ignored_Ghost_Entity (Pack_Id) then 12658 null; 12659 12660 elsif Ekind (Pack_Id) /= E_Generic_Package 12661 and then Requires_Cleanup_Actions 12662 (Specification (Decl), Lib_Level) 12663 then 12664 return True; 12665 end if; 12666 12667 -- Nested package bodies 12668 12669 elsif Nested_Constructs and then Nkind (Decl) = N_Package_Body then 12670 12671 -- Do not inspect an ignored Ghost package body because all code 12672 -- found within will not appear in the final tree. 12673 12674 if Is_Ignored_Ghost_Entity (Defining_Entity (Decl)) then 12675 null; 12676 12677 elsif Ekind (Corresponding_Spec (Decl)) /= E_Generic_Package 12678 and then Requires_Cleanup_Actions (Decl, Lib_Level) 12679 then 12680 return True; 12681 end if; 12682 12683 elsif Nkind (Decl) = N_Block_Statement 12684 and then 12685 12686 -- Handle a rare case caused by a controlled transient object 12687 -- created as part of a record init proc. The variable is wrapped 12688 -- in a block, but the block is not associated with a transient 12689 -- scope. 12690 12691 (Inside_Init_Proc 12692 12693 -- Handle the case where the original context has been wrapped in 12694 -- a block to avoid interference between exception handlers and 12695 -- At_End handlers. Treat the block as transparent and process its 12696 -- contents. 12697 12698 or else Is_Finalization_Wrapper (Decl)) 12699 then 12700 if Requires_Cleanup_Actions (Decl, Lib_Level) then 12701 return True; 12702 end if; 12703 end if; 12704 12705 Next (Decl); 12706 end loop; 12707 12708 return False; 12709 end Requires_Cleanup_Actions; 12710 12711 ------------------------------------ 12712 -- Safe_Unchecked_Type_Conversion -- 12713 ------------------------------------ 12714 12715 -- Note: this function knows quite a bit about the exact requirements of 12716 -- Gigi with respect to unchecked type conversions, and its code must be 12717 -- coordinated with any changes in Gigi in this area. 12718 12719 -- The above requirements should be documented in Sinfo ??? 12720 12721 function Safe_Unchecked_Type_Conversion (Exp : Node_Id) return Boolean is 12722 Otyp : Entity_Id; 12723 Ityp : Entity_Id; 12724 Oalign : Uint; 12725 Ialign : Uint; 12726 Pexp : constant Node_Id := Parent (Exp); 12727 12728 begin 12729 -- If the expression is the RHS of an assignment or object declaration 12730 -- we are always OK because there will always be a target. 12731 12732 -- Object renaming declarations, (generated for view conversions of 12733 -- actuals in inlined calls), like object declarations, provide an 12734 -- explicit type, and are safe as well. 12735 12736 if (Nkind (Pexp) = N_Assignment_Statement 12737 and then Expression (Pexp) = Exp) 12738 or else Nkind (Pexp) 12739 in N_Object_Declaration | N_Object_Renaming_Declaration 12740 then 12741 return True; 12742 12743 -- If the expression is the prefix of an N_Selected_Component we should 12744 -- also be OK because GCC knows to look inside the conversion except if 12745 -- the type is discriminated. We assume that we are OK anyway if the 12746 -- type is not set yet or if it is controlled since we can't afford to 12747 -- introduce a temporary in this case. 12748 12749 elsif Nkind (Pexp) = N_Selected_Component 12750 and then Prefix (Pexp) = Exp 12751 then 12752 return No (Etype (Pexp)) 12753 or else not Is_Type (Etype (Pexp)) 12754 or else not Has_Discriminants (Etype (Pexp)) 12755 or else Is_Constrained (Etype (Pexp)); 12756 end if; 12757 12758 -- Set the output type, this comes from Etype if it is set, otherwise we 12759 -- take it from the subtype mark, which we assume was already fully 12760 -- analyzed. 12761 12762 if Present (Etype (Exp)) then 12763 Otyp := Etype (Exp); 12764 else 12765 Otyp := Entity (Subtype_Mark (Exp)); 12766 end if; 12767 12768 -- The input type always comes from the expression, and we assume this 12769 -- is indeed always analyzed, so we can simply get the Etype. 12770 12771 Ityp := Etype (Expression (Exp)); 12772 12773 -- Initialize alignments to unknown so far 12774 12775 Oalign := No_Uint; 12776 Ialign := No_Uint; 12777 12778 -- Replace a concurrent type by its corresponding record type and each 12779 -- type by its underlying type and do the tests on those. The original 12780 -- type may be a private type whose completion is a concurrent type, so 12781 -- find the underlying type first. 12782 12783 if Present (Underlying_Type (Otyp)) then 12784 Otyp := Underlying_Type (Otyp); 12785 end if; 12786 12787 if Present (Underlying_Type (Ityp)) then 12788 Ityp := Underlying_Type (Ityp); 12789 end if; 12790 12791 if Is_Concurrent_Type (Otyp) then 12792 Otyp := Corresponding_Record_Type (Otyp); 12793 end if; 12794 12795 if Is_Concurrent_Type (Ityp) then 12796 Ityp := Corresponding_Record_Type (Ityp); 12797 end if; 12798 12799 -- If the base types are the same, we know there is no problem since 12800 -- this conversion will be a noop. 12801 12802 if Implementation_Base_Type (Otyp) = Implementation_Base_Type (Ityp) then 12803 return True; 12804 12805 -- Same if this is an upwards conversion of an untagged type, and there 12806 -- are no constraints involved (could be more general???) 12807 12808 elsif Etype (Ityp) = Otyp 12809 and then not Is_Tagged_Type (Ityp) 12810 and then not Has_Discriminants (Ityp) 12811 and then No (First_Rep_Item (Base_Type (Ityp))) 12812 then 12813 return True; 12814 12815 -- If the expression has an access type (object or subprogram) we assume 12816 -- that the conversion is safe, because the size of the target is safe, 12817 -- even if it is a record (which might be treated as having unknown size 12818 -- at this point). 12819 12820 elsif Is_Access_Type (Ityp) then 12821 return True; 12822 12823 -- If the size of output type is known at compile time, there is never 12824 -- a problem. Note that unconstrained records are considered to be of 12825 -- known size, but we can't consider them that way here, because we are 12826 -- talking about the actual size of the object. 12827 12828 -- We also make sure that in addition to the size being known, we do not 12829 -- have a case which might generate an embarrassingly large temp in 12830 -- stack checking mode. 12831 12832 elsif Size_Known_At_Compile_Time (Otyp) 12833 and then 12834 (not Stack_Checking_Enabled 12835 or else not May_Generate_Large_Temp (Otyp)) 12836 and then not (Is_Record_Type (Otyp) and then not Is_Constrained (Otyp)) 12837 then 12838 return True; 12839 12840 -- If either type is tagged, then we know the alignment is OK so Gigi 12841 -- will be able to use pointer punning. 12842 12843 elsif Is_Tagged_Type (Otyp) or else Is_Tagged_Type (Ityp) then 12844 return True; 12845 12846 -- If either type is a limited record type, we cannot do a copy, so say 12847 -- safe since there's nothing else we can do. 12848 12849 elsif Is_Limited_Record (Otyp) or else Is_Limited_Record (Ityp) then 12850 return True; 12851 12852 -- Conversions to and from packed array types are always ignored and 12853 -- hence are safe. 12854 12855 elsif Is_Packed_Array_Impl_Type (Otyp) 12856 or else Is_Packed_Array_Impl_Type (Ityp) 12857 then 12858 return True; 12859 end if; 12860 12861 -- The only other cases known to be safe is if the input type's 12862 -- alignment is known to be at least the maximum alignment for the 12863 -- target or if both alignments are known and the output type's 12864 -- alignment is no stricter than the input's. We can use the component 12865 -- type alignment for an array if a type is an unpacked array type. 12866 12867 if Present (Alignment_Clause (Otyp)) then 12868 Oalign := Expr_Value (Expression (Alignment_Clause (Otyp))); 12869 12870 elsif Is_Array_Type (Otyp) 12871 and then Present (Alignment_Clause (Component_Type (Otyp))) 12872 then 12873 Oalign := Expr_Value (Expression (Alignment_Clause 12874 (Component_Type (Otyp)))); 12875 end if; 12876 12877 if Present (Alignment_Clause (Ityp)) then 12878 Ialign := Expr_Value (Expression (Alignment_Clause (Ityp))); 12879 12880 elsif Is_Array_Type (Ityp) 12881 and then Present (Alignment_Clause (Component_Type (Ityp))) 12882 then 12883 Ialign := Expr_Value (Expression (Alignment_Clause 12884 (Component_Type (Ityp)))); 12885 end if; 12886 12887 if Ialign /= No_Uint and then Ialign > Maximum_Alignment then 12888 return True; 12889 12890 elsif Ialign /= No_Uint 12891 and then Oalign /= No_Uint 12892 and then Ialign <= Oalign 12893 then 12894 return True; 12895 12896 -- Otherwise, Gigi cannot handle this and we must make a temporary 12897 12898 else 12899 return False; 12900 end if; 12901 end Safe_Unchecked_Type_Conversion; 12902 12903 --------------------------------- 12904 -- Set_Current_Value_Condition -- 12905 --------------------------------- 12906 12907 -- Note: the implementation of this procedure is very closely tied to the 12908 -- implementation of Get_Current_Value_Condition. Here we set required 12909 -- Current_Value fields, and in Get_Current_Value_Condition, we interpret 12910 -- them, so they must have a consistent view. 12911 12912 procedure Set_Current_Value_Condition (Cnode : Node_Id) is 12913 12914 procedure Set_Entity_Current_Value (N : Node_Id); 12915 -- If N is an entity reference, where the entity is of an appropriate 12916 -- kind, then set the current value of this entity to Cnode, unless 12917 -- there is already a definite value set there. 12918 12919 procedure Set_Expression_Current_Value (N : Node_Id); 12920 -- If N is of an appropriate form, sets an appropriate entry in current 12921 -- value fields of relevant entities. Multiple entities can be affected 12922 -- in the case of an AND or AND THEN. 12923 12924 ------------------------------ 12925 -- Set_Entity_Current_Value -- 12926 ------------------------------ 12927 12928 procedure Set_Entity_Current_Value (N : Node_Id) is 12929 begin 12930 if Is_Entity_Name (N) then 12931 declare 12932 Ent : constant Entity_Id := Entity (N); 12933 12934 begin 12935 -- Don't capture if not safe to do so 12936 12937 if not Safe_To_Capture_Value (N, Ent, Cond => True) then 12938 return; 12939 end if; 12940 12941 -- Here we have a case where the Current_Value field may need 12942 -- to be set. We set it if it is not already set to a compile 12943 -- time expression value. 12944 12945 -- Note that this represents a decision that one condition 12946 -- blots out another previous one. That's certainly right if 12947 -- they occur at the same level. If the second one is nested, 12948 -- then the decision is neither right nor wrong (it would be 12949 -- equally OK to leave the outer one in place, or take the new 12950 -- inner one). Really we should record both, but our data 12951 -- structures are not that elaborate. 12952 12953 if Nkind (Current_Value (Ent)) not in N_Subexpr then 12954 Set_Current_Value (Ent, Cnode); 12955 end if; 12956 end; 12957 end if; 12958 end Set_Entity_Current_Value; 12959 12960 ---------------------------------- 12961 -- Set_Expression_Current_Value -- 12962 ---------------------------------- 12963 12964 procedure Set_Expression_Current_Value (N : Node_Id) is 12965 Cond : Node_Id; 12966 12967 begin 12968 Cond := N; 12969 12970 -- Loop to deal with (ignore for now) any NOT operators present. The 12971 -- presence of NOT operators will be handled properly when we call 12972 -- Get_Current_Value_Condition. 12973 12974 while Nkind (Cond) = N_Op_Not loop 12975 Cond := Right_Opnd (Cond); 12976 end loop; 12977 12978 -- For an AND or AND THEN, recursively process operands 12979 12980 if Nkind (Cond) = N_Op_And or else Nkind (Cond) = N_And_Then then 12981 Set_Expression_Current_Value (Left_Opnd (Cond)); 12982 Set_Expression_Current_Value (Right_Opnd (Cond)); 12983 return; 12984 end if; 12985 12986 -- Check possible relational operator 12987 12988 if Nkind (Cond) in N_Op_Compare then 12989 if Compile_Time_Known_Value (Right_Opnd (Cond)) then 12990 Set_Entity_Current_Value (Left_Opnd (Cond)); 12991 elsif Compile_Time_Known_Value (Left_Opnd (Cond)) then 12992 Set_Entity_Current_Value (Right_Opnd (Cond)); 12993 end if; 12994 12995 elsif Nkind (Cond) in N_Type_Conversion 12996 | N_Qualified_Expression 12997 | N_Expression_With_Actions 12998 then 12999 Set_Expression_Current_Value (Expression (Cond)); 13000 13001 -- Check possible boolean variable reference 13002 13003 else 13004 Set_Entity_Current_Value (Cond); 13005 end if; 13006 end Set_Expression_Current_Value; 13007 13008 -- Start of processing for Set_Current_Value_Condition 13009 13010 begin 13011 Set_Expression_Current_Value (Condition (Cnode)); 13012 end Set_Current_Value_Condition; 13013 13014 -------------------------- 13015 -- Set_Elaboration_Flag -- 13016 -------------------------- 13017 13018 procedure Set_Elaboration_Flag (N : Node_Id; Spec_Id : Entity_Id) is 13019 Loc : constant Source_Ptr := Sloc (N); 13020 Ent : constant Entity_Id := Elaboration_Entity (Spec_Id); 13021 Asn : Node_Id; 13022 13023 begin 13024 if Present (Ent) then 13025 13026 -- Nothing to do if at the compilation unit level, because in this 13027 -- case the flag is set by the binder generated elaboration routine. 13028 13029 if Nkind (Parent (N)) = N_Compilation_Unit then 13030 null; 13031 13032 -- Here we do need to generate an assignment statement 13033 13034 else 13035 Check_Restriction (No_Elaboration_Code, N); 13036 13037 Asn := 13038 Make_Assignment_Statement (Loc, 13039 Name => New_Occurrence_Of (Ent, Loc), 13040 Expression => Make_Integer_Literal (Loc, Uint_1)); 13041 13042 -- Mark the assignment statement as elaboration code. This allows 13043 -- the early call region mechanism (see Sem_Elab) to properly 13044 -- ignore such assignments even though they are nonpreelaborable 13045 -- code. 13046 13047 Set_Is_Elaboration_Code (Asn); 13048 13049 if Nkind (Parent (N)) = N_Subunit then 13050 Insert_After (Corresponding_Stub (Parent (N)), Asn); 13051 else 13052 Insert_After (N, Asn); 13053 end if; 13054 13055 Analyze (Asn); 13056 13057 -- Kill current value indication. This is necessary because the 13058 -- tests of this flag are inserted out of sequence and must not 13059 -- pick up bogus indications of the wrong constant value. 13060 13061 Set_Current_Value (Ent, Empty); 13062 13063 -- If the subprogram is in the current declarative part and 13064 -- 'access has been applied to it, generate an elaboration 13065 -- check at the beginning of the declarations of the body. 13066 13067 if Nkind (N) = N_Subprogram_Body 13068 and then Address_Taken (Spec_Id) 13069 and then 13070 Ekind (Scope (Spec_Id)) in E_Block | E_Procedure | E_Function 13071 then 13072 declare 13073 Loc : constant Source_Ptr := Sloc (N); 13074 Decls : constant List_Id := Declarations (N); 13075 Chk : Node_Id; 13076 13077 begin 13078 -- No need to generate this check if first entry in the 13079 -- declaration list is a raise of Program_Error now. 13080 13081 if Present (Decls) 13082 and then Nkind (First (Decls)) = N_Raise_Program_Error 13083 then 13084 return; 13085 end if; 13086 13087 -- Otherwise generate the check 13088 13089 Chk := 13090 Make_Raise_Program_Error (Loc, 13091 Condition => 13092 Make_Op_Eq (Loc, 13093 Left_Opnd => New_Occurrence_Of (Ent, Loc), 13094 Right_Opnd => Make_Integer_Literal (Loc, Uint_0)), 13095 Reason => PE_Access_Before_Elaboration); 13096 13097 if No (Decls) then 13098 Set_Declarations (N, New_List (Chk)); 13099 else 13100 Prepend (Chk, Decls); 13101 end if; 13102 13103 Analyze (Chk); 13104 end; 13105 end if; 13106 end if; 13107 end if; 13108 end Set_Elaboration_Flag; 13109 13110 ---------------------------- 13111 -- Set_Renamed_Subprogram -- 13112 ---------------------------- 13113 13114 procedure Set_Renamed_Subprogram (N : Node_Id; E : Entity_Id) is 13115 begin 13116 -- If input node is an identifier, we can just reset it 13117 13118 if Nkind (N) = N_Identifier then 13119 Set_Chars (N, Chars (E)); 13120 Set_Entity (N, E); 13121 13122 -- Otherwise we have to do a rewrite, preserving Comes_From_Source 13123 13124 else 13125 declare 13126 CS : constant Boolean := Comes_From_Source (N); 13127 begin 13128 Rewrite (N, Make_Identifier (Sloc (N), Chars (E))); 13129 Set_Entity (N, E); 13130 Set_Comes_From_Source (N, CS); 13131 Set_Analyzed (N, True); 13132 end; 13133 end if; 13134 end Set_Renamed_Subprogram; 13135 13136 ---------------------- 13137 -- Side_Effect_Free -- 13138 ---------------------- 13139 13140 function Side_Effect_Free 13141 (N : Node_Id; 13142 Name_Req : Boolean := False; 13143 Variable_Ref : Boolean := False) return Boolean 13144 is 13145 Typ : constant Entity_Id := Etype (N); 13146 -- Result type of the expression 13147 13148 function Safe_Prefixed_Reference (N : Node_Id) return Boolean; 13149 -- The argument N is a construct where the Prefix is dereferenced if it 13150 -- is an access type and the result is a variable. The call returns True 13151 -- if the construct is side effect free (not considering side effects in 13152 -- other than the prefix which are to be tested by the caller). 13153 13154 function Within_In_Parameter (N : Node_Id) return Boolean; 13155 -- Determines if N is a subcomponent of a composite in-parameter. If so, 13156 -- N is not side-effect free when the actual is global and modifiable 13157 -- indirectly from within a subprogram, because it may be passed by 13158 -- reference. The front-end must be conservative here and assume that 13159 -- this may happen with any array or record type. On the other hand, we 13160 -- cannot create temporaries for all expressions for which this 13161 -- condition is true, for various reasons that might require clearing up 13162 -- ??? For example, discriminant references that appear out of place, or 13163 -- spurious type errors with class-wide expressions. As a result, we 13164 -- limit the transformation to loop bounds, which is so far the only 13165 -- case that requires it. 13166 13167 ----------------------------- 13168 -- Safe_Prefixed_Reference -- 13169 ----------------------------- 13170 13171 function Safe_Prefixed_Reference (N : Node_Id) return Boolean is 13172 begin 13173 -- If prefix is not side effect free, definitely not safe 13174 13175 if not Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref) then 13176 return False; 13177 13178 -- If the prefix is of an access type that is not access-to-constant, 13179 -- then this construct is a variable reference, which means it is to 13180 -- be considered to have side effects if Variable_Ref is set True. 13181 13182 elsif Is_Access_Type (Etype (Prefix (N))) 13183 and then not Is_Access_Constant (Etype (Prefix (N))) 13184 and then Variable_Ref 13185 then 13186 -- Exception is a prefix that is the result of a previous removal 13187 -- of side effects. 13188 13189 return Is_Entity_Name (Prefix (N)) 13190 and then not Comes_From_Source (Prefix (N)) 13191 and then Ekind (Entity (Prefix (N))) = E_Constant 13192 and then Is_Internal_Name (Chars (Entity (Prefix (N)))); 13193 13194 -- If the prefix is an explicit dereference then this construct is a 13195 -- variable reference, which means it is to be considered to have 13196 -- side effects if Variable_Ref is True. 13197 13198 -- We do NOT exclude dereferences of access-to-constant types because 13199 -- we handle them as constant view of variables. 13200 13201 elsif Nkind (Prefix (N)) = N_Explicit_Dereference 13202 and then Variable_Ref 13203 then 13204 return False; 13205 13206 -- Note: The following test is the simplest way of solving a complex 13207 -- problem uncovered by the following test (Side effect on loop bound 13208 -- that is a subcomponent of a global variable: 13209 13210 -- with Text_Io; use Text_Io; 13211 -- procedure Tloop is 13212 -- type X is 13213 -- record 13214 -- V : Natural := 4; 13215 -- S : String (1..5) := (others => 'a'); 13216 -- end record; 13217 -- X1 : X; 13218 13219 -- procedure Modi; 13220 13221 -- generic 13222 -- with procedure Action; 13223 -- procedure Loop_G (Arg : X; Msg : String) 13224 13225 -- procedure Loop_G (Arg : X; Msg : String) is 13226 -- begin 13227 -- Put_Line ("begin loop_g " & Msg & " will loop till: " 13228 -- & Natural'Image (Arg.V)); 13229 -- for Index in 1 .. Arg.V loop 13230 -- Text_Io.Put_Line 13231 -- (Natural'Image (Index) & " " & Arg.S (Index)); 13232 -- if Index > 2 then 13233 -- Modi; 13234 -- end if; 13235 -- end loop; 13236 -- Put_Line ("end loop_g " & Msg); 13237 -- end; 13238 13239 -- procedure Loop1 is new Loop_G (Modi); 13240 -- procedure Modi is 13241 -- begin 13242 -- X1.V := 1; 13243 -- Loop1 (X1, "from modi"); 13244 -- end; 13245 -- 13246 -- begin 13247 -- Loop1 (X1, "initial"); 13248 -- end; 13249 13250 -- The output of the above program should be: 13251 13252 -- begin loop_g initial will loop till: 4 13253 -- 1 a 13254 -- 2 a 13255 -- 3 a 13256 -- begin loop_g from modi will loop till: 1 13257 -- 1 a 13258 -- end loop_g from modi 13259 -- 4 a 13260 -- begin loop_g from modi will loop till: 1 13261 -- 1 a 13262 -- end loop_g from modi 13263 -- end loop_g initial 13264 13265 -- If a loop bound is a subcomponent of a global variable, a 13266 -- modification of that variable within the loop may incorrectly 13267 -- affect the execution of the loop. 13268 13269 elsif Nkind (Parent (Parent (N))) = N_Loop_Parameter_Specification 13270 and then Within_In_Parameter (Prefix (N)) 13271 and then Variable_Ref 13272 then 13273 return False; 13274 13275 -- All other cases are side effect free 13276 13277 else 13278 return True; 13279 end if; 13280 end Safe_Prefixed_Reference; 13281 13282 ------------------------- 13283 -- Within_In_Parameter -- 13284 ------------------------- 13285 13286 function Within_In_Parameter (N : Node_Id) return Boolean is 13287 begin 13288 if not Comes_From_Source (N) then 13289 return False; 13290 13291 elsif Is_Entity_Name (N) then 13292 return Ekind (Entity (N)) = E_In_Parameter; 13293 13294 elsif Nkind (N) in N_Indexed_Component | N_Selected_Component then 13295 return Within_In_Parameter (Prefix (N)); 13296 13297 else 13298 return False; 13299 end if; 13300 end Within_In_Parameter; 13301 13302 -- Start of processing for Side_Effect_Free 13303 13304 begin 13305 -- If volatile reference, always consider it to have side effects 13306 13307 if Is_Volatile_Reference (N) then 13308 return False; 13309 end if; 13310 13311 -- Note on checks that could raise Constraint_Error. Strictly, if we 13312 -- take advantage of 11.6, these checks do not count as side effects. 13313 -- However, we would prefer to consider that they are side effects, 13314 -- since the back end CSE does not work very well on expressions which 13315 -- can raise Constraint_Error. On the other hand if we don't consider 13316 -- them to be side effect free, then we get some awkward expansions 13317 -- in -gnato mode, resulting in code insertions at a point where we 13318 -- do not have a clear model for performing the insertions. 13319 13320 -- Special handling for entity names 13321 13322 if Is_Entity_Name (N) then 13323 13324 -- A type reference is always side effect free 13325 13326 if Is_Type (Entity (N)) then 13327 return True; 13328 13329 -- Variables are considered to be a side effect if Variable_Ref 13330 -- is set or if we have a volatile reference and Name_Req is off. 13331 -- If Name_Req is True then we can't help returning a name which 13332 -- effectively allows multiple references in any case. 13333 13334 elsif Is_Variable (N, Use_Original_Node => False) then 13335 return not Variable_Ref 13336 and then (not Is_Volatile_Reference (N) or else Name_Req); 13337 13338 -- Any other entity (e.g. a subtype name) is definitely side 13339 -- effect free. 13340 13341 else 13342 return True; 13343 end if; 13344 13345 -- A value known at compile time is always side effect free 13346 13347 elsif Compile_Time_Known_Value (N) then 13348 return True; 13349 13350 -- A variable renaming is not side-effect free, because the renaming 13351 -- will function like a macro in the front-end in some cases, and an 13352 -- assignment can modify the component designated by N, so we need to 13353 -- create a temporary for it. 13354 13355 -- The guard testing for Entity being present is needed at least in 13356 -- the case of rewritten predicate expressions, and may well also be 13357 -- appropriate elsewhere. Obviously we can't go testing the entity 13358 -- field if it does not exist, so it's reasonable to say that this is 13359 -- not the renaming case if it does not exist. 13360 13361 elsif Is_Entity_Name (Original_Node (N)) 13362 and then Present (Entity (Original_Node (N))) 13363 and then Is_Renaming_Of_Object (Entity (Original_Node (N))) 13364 and then Ekind (Entity (Original_Node (N))) /= E_Constant 13365 then 13366 declare 13367 RO : constant Node_Id := 13368 Renamed_Object (Entity (Original_Node (N))); 13369 13370 begin 13371 -- If the renamed object is an indexed component, or an 13372 -- explicit dereference, then the designated object could 13373 -- be modified by an assignment. 13374 13375 if Nkind (RO) in N_Indexed_Component | N_Explicit_Dereference then 13376 return False; 13377 13378 -- A selected component must have a safe prefix 13379 13380 elsif Nkind (RO) = N_Selected_Component then 13381 return Safe_Prefixed_Reference (RO); 13382 13383 -- In all other cases, designated object cannot be changed so 13384 -- we are side effect free. 13385 13386 else 13387 return True; 13388 end if; 13389 end; 13390 13391 -- Remove_Side_Effects generates an object renaming declaration to 13392 -- capture the expression of a class-wide expression. In VM targets 13393 -- the frontend performs no expansion for dispatching calls to 13394 -- class- wide types since they are handled by the VM. Hence, we must 13395 -- locate here if this node corresponds to a previous invocation of 13396 -- Remove_Side_Effects to avoid a never ending loop in the frontend. 13397 13398 elsif not Tagged_Type_Expansion 13399 and then not Comes_From_Source (N) 13400 and then Nkind (Parent (N)) = N_Object_Renaming_Declaration 13401 and then Is_Class_Wide_Type (Typ) 13402 then 13403 return True; 13404 13405 -- Generating C the type conversion of an access to constrained array 13406 -- type into an access to unconstrained array type involves initializing 13407 -- a fat pointer and the expression cannot be assumed to be free of side 13408 -- effects since it must referenced several times to compute its bounds. 13409 13410 elsif Modify_Tree_For_C 13411 and then Nkind (N) = N_Type_Conversion 13412 and then Is_Access_Type (Typ) 13413 and then Is_Array_Type (Designated_Type (Typ)) 13414 and then not Is_Constrained (Designated_Type (Typ)) 13415 then 13416 return False; 13417 end if; 13418 13419 -- For other than entity names and compile time known values, 13420 -- check the node kind for special processing. 13421 13422 case Nkind (N) is 13423 13424 -- An attribute reference is side-effect free if its expressions 13425 -- are side-effect free and its prefix is side-effect free or is 13426 -- an entity reference. 13427 13428 when N_Attribute_Reference => 13429 return Side_Effect_Free_Attribute (Attribute_Name (N)) 13430 and then 13431 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref) 13432 and then 13433 (Is_Entity_Name (Prefix (N)) 13434 or else 13435 Side_Effect_Free (Prefix (N), Name_Req, Variable_Ref)); 13436 13437 -- A binary operator is side effect free if and both operands are 13438 -- side effect free. For this purpose binary operators include 13439 -- membership tests and short circuit forms. 13440 13441 when N_Binary_Op 13442 | N_Membership_Test 13443 | N_Short_Circuit 13444 => 13445 return Side_Effect_Free (Left_Opnd (N), Name_Req, Variable_Ref) 13446 and then 13447 Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref); 13448 13449 -- An explicit dereference is side effect free only if it is 13450 -- a side effect free prefixed reference. 13451 13452 when N_Explicit_Dereference => 13453 return Safe_Prefixed_Reference (N); 13454 13455 -- An expression with action is side effect free if its expression 13456 -- is side effect free and it has no actions. 13457 13458 when N_Expression_With_Actions => 13459 return 13460 Is_Empty_List (Actions (N)) 13461 and then Side_Effect_Free 13462 (Expression (N), Name_Req, Variable_Ref); 13463 13464 -- A call to _rep_to_pos is side effect free, since we generate 13465 -- this pure function call ourselves. Moreover it is critically 13466 -- important to make this exception, since otherwise we can have 13467 -- discriminants in array components which don't look side effect 13468 -- free in the case of an array whose index type is an enumeration 13469 -- type with an enumeration rep clause. 13470 13471 -- All other function calls are not side effect free 13472 13473 when N_Function_Call => 13474 return 13475 Nkind (Name (N)) = N_Identifier 13476 and then Is_TSS (Name (N), TSS_Rep_To_Pos) 13477 and then Side_Effect_Free 13478 (First (Parameter_Associations (N)), 13479 Name_Req, Variable_Ref); 13480 13481 -- An IF expression is side effect free if it's of a scalar type, and 13482 -- all its components are all side effect free (conditions and then 13483 -- actions and else actions). We restrict to scalar types, since it 13484 -- is annoying to deal with things like (if A then B else C)'First 13485 -- where the type involved is a string type. 13486 13487 when N_If_Expression => 13488 return 13489 Is_Scalar_Type (Typ) 13490 and then Side_Effect_Free 13491 (Expressions (N), Name_Req, Variable_Ref); 13492 13493 -- An indexed component is side effect free if it is a side 13494 -- effect free prefixed reference and all the indexing 13495 -- expressions are side effect free. 13496 13497 when N_Indexed_Component => 13498 return 13499 Side_Effect_Free (Expressions (N), Name_Req, Variable_Ref) 13500 and then Safe_Prefixed_Reference (N); 13501 13502 -- A type qualification, type conversion, or unchecked expression is 13503 -- side effect free if the expression is side effect free. 13504 13505 when N_Qualified_Expression 13506 | N_Type_Conversion 13507 | N_Unchecked_Expression 13508 => 13509 return Side_Effect_Free (Expression (N), Name_Req, Variable_Ref); 13510 13511 -- A selected component is side effect free only if it is a side 13512 -- effect free prefixed reference. 13513 13514 when N_Selected_Component => 13515 return Safe_Prefixed_Reference (N); 13516 13517 -- A range is side effect free if the bounds are side effect free 13518 13519 when N_Range => 13520 return Side_Effect_Free (Low_Bound (N), Name_Req, Variable_Ref) 13521 and then 13522 Side_Effect_Free (High_Bound (N), Name_Req, Variable_Ref); 13523 13524 -- A slice is side effect free if it is a side effect free 13525 -- prefixed reference and the bounds are side effect free. 13526 13527 when N_Slice => 13528 return 13529 Side_Effect_Free (Discrete_Range (N), Name_Req, Variable_Ref) 13530 and then Safe_Prefixed_Reference (N); 13531 13532 -- A unary operator is side effect free if the operand 13533 -- is side effect free. 13534 13535 when N_Unary_Op => 13536 return Side_Effect_Free (Right_Opnd (N), Name_Req, Variable_Ref); 13537 13538 -- An unchecked type conversion is side effect free only if it 13539 -- is safe and its argument is side effect free. 13540 13541 when N_Unchecked_Type_Conversion => 13542 return 13543 Safe_Unchecked_Type_Conversion (N) 13544 and then Side_Effect_Free 13545 (Expression (N), Name_Req, Variable_Ref); 13546 13547 -- A literal is side effect free 13548 13549 when N_Character_Literal 13550 | N_Integer_Literal 13551 | N_Real_Literal 13552 | N_String_Literal 13553 => 13554 return True; 13555 13556 -- An aggregate is side effect free if all its values are compile 13557 -- time known. 13558 13559 when N_Aggregate => 13560 return Compile_Time_Known_Aggregate (N); 13561 13562 -- We consider that anything else has side effects. This is a bit 13563 -- crude, but we are pretty close for most common cases, and we 13564 -- are certainly correct (i.e. we never return True when the 13565 -- answer should be False). 13566 13567 when others => 13568 return False; 13569 end case; 13570 end Side_Effect_Free; 13571 13572 -- A list is side effect free if all elements of the list are side 13573 -- effect free. 13574 13575 function Side_Effect_Free 13576 (L : List_Id; 13577 Name_Req : Boolean := False; 13578 Variable_Ref : Boolean := False) return Boolean 13579 is 13580 N : Node_Id; 13581 13582 begin 13583 if L = No_List or else L = Error_List then 13584 return True; 13585 13586 else 13587 N := First (L); 13588 while Present (N) loop 13589 if not Side_Effect_Free (N, Name_Req, Variable_Ref) then 13590 return False; 13591 else 13592 Next (N); 13593 end if; 13594 end loop; 13595 13596 return True; 13597 end if; 13598 end Side_Effect_Free; 13599 13600 -------------------------------- 13601 -- Side_Effect_Free_Attribute -- 13602 -------------------------------- 13603 13604 function Side_Effect_Free_Attribute (Name : Name_Id) return Boolean is 13605 begin 13606 case Name is 13607 when Name_Input => 13608 return False; 13609 13610 when Name_Image 13611 | Name_Img 13612 | Name_Wide_Image 13613 | Name_Wide_Wide_Image 13614 => 13615 -- CodePeer doesn't want to see replicated copies of 'Image calls 13616 13617 return not CodePeer_Mode; 13618 13619 when others => 13620 return True; 13621 end case; 13622 end Side_Effect_Free_Attribute; 13623 13624 ---------------------------------- 13625 -- Silly_Boolean_Array_Not_Test -- 13626 ---------------------------------- 13627 13628 -- This procedure implements an odd and silly test. We explicitly check 13629 -- for the case where the 'First of the component type is equal to the 13630 -- 'Last of this component type, and if this is the case, we make sure 13631 -- that constraint error is raised. The reason is that the NOT is bound 13632 -- to cause CE in this case, and we will not otherwise catch it. 13633 13634 -- No such check is required for AND and OR, since for both these cases 13635 -- False op False = False, and True op True = True. For the XOR case, 13636 -- see Silly_Boolean_Array_Xor_Test. 13637 13638 -- Believe it or not, this was reported as a bug. Note that nearly always, 13639 -- the test will evaluate statically to False, so the code will be 13640 -- statically removed, and no extra overhead caused. 13641 13642 procedure Silly_Boolean_Array_Not_Test (N : Node_Id; T : Entity_Id) is 13643 Loc : constant Source_Ptr := Sloc (N); 13644 CT : constant Entity_Id := Component_Type (T); 13645 13646 begin 13647 -- The check we install is 13648 13649 -- constraint_error when 13650 -- component_type'first = component_type'last 13651 -- and then array_type'Length /= 0) 13652 13653 -- We need the last guard because we don't want to raise CE for empty 13654 -- arrays since no out of range values result. (Empty arrays with a 13655 -- component type of True .. True -- very useful -- even the ACATS 13656 -- does not test that marginal case). 13657 13658 Insert_Action (N, 13659 Make_Raise_Constraint_Error (Loc, 13660 Condition => 13661 Make_And_Then (Loc, 13662 Left_Opnd => 13663 Make_Op_Eq (Loc, 13664 Left_Opnd => 13665 Make_Attribute_Reference (Loc, 13666 Prefix => New_Occurrence_Of (CT, Loc), 13667 Attribute_Name => Name_First), 13668 13669 Right_Opnd => 13670 Make_Attribute_Reference (Loc, 13671 Prefix => New_Occurrence_Of (CT, Loc), 13672 Attribute_Name => Name_Last)), 13673 13674 Right_Opnd => Make_Non_Empty_Check (Loc, Right_Opnd (N))), 13675 Reason => CE_Range_Check_Failed)); 13676 end Silly_Boolean_Array_Not_Test; 13677 13678 ---------------------------------- 13679 -- Silly_Boolean_Array_Xor_Test -- 13680 ---------------------------------- 13681 13682 -- This procedure implements an odd and silly test. We explicitly check 13683 -- for the XOR case where the component type is True .. True, since this 13684 -- will raise constraint error. A special check is required since CE 13685 -- will not be generated otherwise (cf Expand_Packed_Not). 13686 13687 -- No such check is required for AND and OR, since for both these cases 13688 -- False op False = False, and True op True = True, and no check is 13689 -- required for the case of False .. False, since False xor False = False. 13690 -- See also Silly_Boolean_Array_Not_Test 13691 13692 procedure Silly_Boolean_Array_Xor_Test 13693 (N : Node_Id; 13694 R : Node_Id; 13695 T : Entity_Id) 13696 is 13697 Loc : constant Source_Ptr := Sloc (N); 13698 CT : constant Entity_Id := Component_Type (T); 13699 13700 begin 13701 -- The check we install is 13702 13703 -- constraint_error when 13704 -- Boolean (component_type'First) 13705 -- and then Boolean (component_type'Last) 13706 -- and then array_type'Length /= 0) 13707 13708 -- We need the last guard because we don't want to raise CE for empty 13709 -- arrays since no out of range values result (Empty arrays with a 13710 -- component type of True .. True -- very useful -- even the ACATS 13711 -- does not test that marginal case). 13712 13713 Insert_Action (N, 13714 Make_Raise_Constraint_Error (Loc, 13715 Condition => 13716 Make_And_Then (Loc, 13717 Left_Opnd => 13718 Make_And_Then (Loc, 13719 Left_Opnd => 13720 Convert_To (Standard_Boolean, 13721 Make_Attribute_Reference (Loc, 13722 Prefix => New_Occurrence_Of (CT, Loc), 13723 Attribute_Name => Name_First)), 13724 13725 Right_Opnd => 13726 Convert_To (Standard_Boolean, 13727 Make_Attribute_Reference (Loc, 13728 Prefix => New_Occurrence_Of (CT, Loc), 13729 Attribute_Name => Name_Last))), 13730 13731 Right_Opnd => Make_Non_Empty_Check (Loc, R)), 13732 Reason => CE_Range_Check_Failed)); 13733 end Silly_Boolean_Array_Xor_Test; 13734 13735 ---------------------------- 13736 -- Small_Integer_Type_For -- 13737 ---------------------------- 13738 13739 function Small_Integer_Type_For (S : Uint; Uns : Boolean) return Entity_Id 13740 is 13741 begin 13742 pragma Assert (S <= System_Max_Integer_Size); 13743 13744 if S <= Standard_Short_Short_Integer_Size then 13745 if Uns then 13746 return Standard_Short_Short_Unsigned; 13747 else 13748 return Standard_Short_Short_Integer; 13749 end if; 13750 13751 elsif S <= Standard_Short_Integer_Size then 13752 if Uns then 13753 return Standard_Short_Unsigned; 13754 else 13755 return Standard_Short_Integer; 13756 end if; 13757 13758 elsif S <= Standard_Integer_Size then 13759 if Uns then 13760 return Standard_Unsigned; 13761 else 13762 return Standard_Integer; 13763 end if; 13764 13765 elsif S <= Standard_Long_Integer_Size then 13766 if Uns then 13767 return Standard_Long_Unsigned; 13768 else 13769 return Standard_Long_Integer; 13770 end if; 13771 13772 elsif S <= Standard_Long_Long_Integer_Size then 13773 if Uns then 13774 return Standard_Long_Long_Unsigned; 13775 else 13776 return Standard_Long_Long_Integer; 13777 end if; 13778 13779 elsif S <= Standard_Long_Long_Long_Integer_Size then 13780 if Uns then 13781 return Standard_Long_Long_Long_Unsigned; 13782 else 13783 return Standard_Long_Long_Long_Integer; 13784 end if; 13785 13786 else 13787 raise Program_Error; 13788 end if; 13789 end Small_Integer_Type_For; 13790 13791 ------------------- 13792 -- Type_Map_Hash -- 13793 ------------------- 13794 13795 function Type_Map_Hash (Id : Entity_Id) return Type_Map_Header is 13796 begin 13797 return Type_Map_Header (Id mod Type_Map_Size); 13798 end Type_Map_Hash; 13799 13800 ------------------------------------------ 13801 -- Type_May_Have_Bit_Aligned_Components -- 13802 ------------------------------------------ 13803 13804 function Type_May_Have_Bit_Aligned_Components 13805 (Typ : Entity_Id) return Boolean 13806 is 13807 begin 13808 -- Array type, check component type 13809 13810 if Is_Array_Type (Typ) then 13811 return 13812 Type_May_Have_Bit_Aligned_Components (Component_Type (Typ)); 13813 13814 -- Record type, check components 13815 13816 elsif Is_Record_Type (Typ) then 13817 declare 13818 E : Entity_Id; 13819 13820 begin 13821 E := First_Component_Or_Discriminant (Typ); 13822 while Present (E) loop 13823 -- This is the crucial test: if the component itself causes 13824 -- trouble, then we can stop and return True. 13825 13826 if Component_May_Be_Bit_Aligned (E) then 13827 return True; 13828 end if; 13829 13830 -- Otherwise, we need to test its type, to see if it may 13831 -- itself contain a troublesome component. 13832 13833 if Type_May_Have_Bit_Aligned_Components (Etype (E)) then 13834 return True; 13835 end if; 13836 13837 Next_Component_Or_Discriminant (E); 13838 end loop; 13839 13840 return False; 13841 end; 13842 13843 -- Type other than array or record is always OK 13844 13845 else 13846 return False; 13847 end if; 13848 end Type_May_Have_Bit_Aligned_Components; 13849 13850 ------------------------------- 13851 -- Update_Primitives_Mapping -- 13852 ------------------------------- 13853 13854 procedure Update_Primitives_Mapping 13855 (Inher_Id : Entity_Id; 13856 Subp_Id : Entity_Id) 13857 is 13858 begin 13859 Map_Types 13860 (Parent_Type => Find_Dispatching_Type (Inher_Id), 13861 Derived_Type => Find_Dispatching_Type (Subp_Id)); 13862 end Update_Primitives_Mapping; 13863 13864 ---------------------------------- 13865 -- Within_Case_Or_If_Expression -- 13866 ---------------------------------- 13867 13868 function Within_Case_Or_If_Expression (N : Node_Id) return Boolean is 13869 Par : Node_Id; 13870 13871 begin 13872 -- Locate an enclosing case or if expression. Note that these constructs 13873 -- can be expanded into Expression_With_Actions, hence the test of the 13874 -- original node. 13875 13876 Par := Parent (N); 13877 while Present (Par) loop 13878 if Nkind (Original_Node (Par)) in N_Case_Expression | N_If_Expression 13879 then 13880 return True; 13881 13882 -- Prevent the search from going too far 13883 13884 elsif Is_Body_Or_Package_Declaration (Par) then 13885 return False; 13886 end if; 13887 13888 Par := Parent (Par); 13889 end loop; 13890 13891 return False; 13892 end Within_Case_Or_If_Expression; 13893 13894 ------------------------------ 13895 -- Predicate_Check_In_Scope -- 13896 ------------------------------ 13897 13898 function Predicate_Check_In_Scope (N : Node_Id) return Boolean is 13899 S : Entity_Id; 13900 13901 begin 13902 S := Current_Scope; 13903 while Present (S) and then not Is_Subprogram (S) loop 13904 S := Scope (S); 13905 end loop; 13906 13907 if Present (S) then 13908 13909 -- Predicate checks should only be enabled in init procs for 13910 -- expressions coming from source. 13911 13912 if Is_Init_Proc (S) then 13913 return Comes_From_Source (N); 13914 13915 elsif Get_TSS_Name (S) /= TSS_Null 13916 and then not Is_Predicate_Function (S) 13917 and then not Is_Predicate_Function_M (S) 13918 then 13919 return False; 13920 end if; 13921 end if; 13922 13923 return True; 13924 end Predicate_Check_In_Scope; 13925 13926end Exp_Util; 13927