1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- C O N T R A C T S --
9 -- Copyright (C) 2015-2016, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with Aspects
; use Aspects
;
27 with Atree
; use Atree
;
28 with Einfo
; use Einfo
;
29 with Elists
; use Elists
;
30 with Errout
; use Errout
;
31 with Exp_Prag
; use Exp_Prag
;
32 with Exp_Tss
; use Exp_Tss
;
33 with Exp_Util
; use Exp_Util
;
34 with Namet
; use Namet
;
35 with Nlists
; use Nlists
;
36 with Nmake
; use Nmake
;
39 with Sem_Aux
; use Sem_Aux
;
40 with Sem_Ch6
; use Sem_Ch6
;
41 with Sem_Ch8
; use Sem_Ch8
;
42 with Sem_Ch12
; use Sem_Ch12
;
43 with Sem_Disp
; use Sem_Disp
;
44 with Sem_Prag
; use Sem_Prag
;
45 with Sem_Util
; use Sem_Util
;
46 with Sinfo
; use Sinfo
;
47 with Snames
; use Snames
;
48 with Stringt
; use Stringt
;
49 with Tbuild
; use Tbuild
;
51 package body Contracts
is
53 procedure Analyze_Contracts
56 Freeze_Id
: Entity_Id
);
57 -- Subsidiary to the one parameter version of Analyze_Contracts and routine
58 -- Analyze_Previous_Constracts. Analyze the contracts of all constructs in
59 -- the list L. If Freeze_Nod is set, then the analysis stops when the node
60 -- is reached. Freeze_Id is the entity of some related context which caused
61 -- freezing up to node Freeze_Nod.
63 procedure Expand_Subprogram_Contract
(Body_Id
: Entity_Id
);
64 -- Expand the contracts of a subprogram body and its correspoding spec (if
65 -- any). This routine processes all [refined] pre- and postconditions as
66 -- well as Contract_Cases, invariants and predicates. Body_Id denotes the
67 -- entity of the subprogram body.
69 -----------------------
70 -- Add_Contract_Item --
71 -----------------------
73 procedure Add_Contract_Item
(Prag
: Node_Id
; Id
: Entity_Id
) is
74 Items
: Node_Id
:= Contract
(Id
);
76 procedure Add_Classification
;
77 -- Prepend Prag to the list of classifications
79 procedure Add_Contract_Test_Case
;
80 -- Prepend Prag to the list of contract and test cases
82 procedure Add_Pre_Post_Condition
;
83 -- Prepend Prag to the list of pre- and postconditions
85 ------------------------
86 -- Add_Classification --
87 ------------------------
89 procedure Add_Classification
is
91 Set_Next_Pragma
(Prag
, Classifications
(Items
));
92 Set_Classifications
(Items
, Prag
);
93 end Add_Classification
;
95 ----------------------------
96 -- Add_Contract_Test_Case --
97 ----------------------------
99 procedure Add_Contract_Test_Case
is
101 Set_Next_Pragma
(Prag
, Contract_Test_Cases
(Items
));
102 Set_Contract_Test_Cases
(Items
, Prag
);
103 end Add_Contract_Test_Case
;
105 ----------------------------
106 -- Add_Pre_Post_Condition --
107 ----------------------------
109 procedure Add_Pre_Post_Condition
is
111 Set_Next_Pragma
(Prag
, Pre_Post_Conditions
(Items
));
112 Set_Pre_Post_Conditions
(Items
, Prag
);
113 end Add_Pre_Post_Condition
;
119 -- Start of processing for Add_Contract_Item
122 -- A contract must contain only pragmas
124 pragma Assert
(Nkind
(Prag
) = N_Pragma
);
125 Prag_Nam
:= Pragma_Name
(Prag
);
127 -- Create a new contract when adding the first item
130 Items
:= Make_Contract
(Sloc
(Id
));
131 Set_Contract
(Id
, Items
);
134 -- Constants, the applicable pragmas are:
137 if Ekind
(Id
) = E_Constant
then
138 if Prag_Nam
= Name_Part_Of
then
141 -- The pragma is not a proper contract item
147 -- Entry bodies, the applicable pragmas are:
152 elsif Is_Entry_Body
(Id
) then
153 if Nam_In
(Prag_Nam
, Name_Refined_Depends
, Name_Refined_Global
) then
156 elsif Prag_Nam
= Name_Refined_Post
then
157 Add_Pre_Post_Condition
;
159 -- The pragma is not a proper contract item
165 -- Entry or subprogram declarations, the applicable pragmas are:
169 -- Extensions_Visible
177 elsif Is_Entry_Declaration
(Id
)
178 or else Ekind_In
(Id
, E_Function
,
183 if Nam_In
(Prag_Nam
, Name_Attach_Handler
, Name_Interrupt_Handler
)
184 and then Ekind_In
(Id
, E_Generic_Procedure
, E_Procedure
)
188 elsif Nam_In
(Prag_Nam
, Name_Depends
,
189 Name_Extensions_Visible
,
194 elsif Prag_Nam
= Name_Volatile_Function
195 and then Ekind_In
(Id
, E_Function
, E_Generic_Function
)
199 elsif Nam_In
(Prag_Nam
, Name_Contract_Cases
, Name_Test_Case
) then
200 Add_Contract_Test_Case
;
202 elsif Nam_In
(Prag_Nam
, Name_Postcondition
, Name_Precondition
) then
203 Add_Pre_Post_Condition
;
205 -- The pragma is not a proper contract item
211 -- Packages or instantiations, the applicable pragmas are:
215 -- Part_Of (instantiation only)
217 elsif Ekind_In
(Id
, E_Generic_Package
, E_Package
) then
218 if Nam_In
(Prag_Nam
, Name_Abstract_State
,
219 Name_Initial_Condition
,
224 -- Indicator Part_Of must be associated with a package instantiation
226 elsif Prag_Nam
= Name_Part_Of
and then Is_Generic_Instance
(Id
) then
229 -- The pragma is not a proper contract item
235 -- Package bodies, the applicable pragmas are:
238 elsif Ekind
(Id
) = E_Package_Body
then
239 if Prag_Nam
= Name_Refined_State
then
242 -- The pragma is not a proper contract item
248 -- Protected units, the applicable pragmas are:
251 elsif Ekind
(Id
) = E_Protected_Type
then
252 if Prag_Nam
= Name_Part_Of
then
255 -- The pragma is not a proper contract item
261 -- Subprogram bodies, the applicable pragmas are:
268 elsif Ekind
(Id
) = E_Subprogram_Body
then
269 if Nam_In
(Prag_Nam
, Name_Refined_Depends
, Name_Refined_Global
) then
272 elsif Nam_In
(Prag_Nam
, Name_Postcondition
,
276 Add_Pre_Post_Condition
;
278 -- The pragma is not a proper contract item
284 -- Task bodies, the applicable pragmas are:
288 elsif Ekind
(Id
) = E_Task_Body
then
289 if Nam_In
(Prag_Nam
, Name_Refined_Depends
, Name_Refined_Global
) then
292 -- The pragma is not a proper contract item
298 -- Task units, the applicable pragmas are:
303 elsif Ekind
(Id
) = E_Task_Type
then
304 if Nam_In
(Prag_Nam
, Name_Depends
, Name_Global
, Name_Part_Of
) then
307 -- The pragma is not a proper contract item
313 -- Variables, the applicable pragmas are:
316 -- Constant_After_Elaboration
323 elsif Ekind
(Id
) = E_Variable
then
324 if Nam_In
(Prag_Nam
, Name_Async_Readers
,
326 Name_Constant_After_Elaboration
,
328 Name_Effective_Reads
,
329 Name_Effective_Writes
,
335 -- The pragma is not a proper contract item
341 end Add_Contract_Item
;
343 -----------------------
344 -- Analyze_Contracts --
345 -----------------------
347 procedure Analyze_Contracts
(L
: List_Id
) is
349 Analyze_Contracts
(L
, Freeze_Nod
=> Empty
, Freeze_Id
=> Empty
);
350 end Analyze_Contracts
;
352 procedure Analyze_Contracts
354 Freeze_Nod
: Node_Id
;
355 Freeze_Id
: Entity_Id
)
361 while Present
(Decl
) loop
363 -- The caller requests that the traversal stops at a particular node
364 -- that causes contract "freezing".
366 if Present
(Freeze_Nod
) and then Decl
= Freeze_Nod
then
370 -- Entry or subprogram declarations
372 if Nkind_In
(Decl
, N_Abstract_Subprogram_Declaration
,
374 N_Generic_Subprogram_Declaration
,
375 N_Subprogram_Declaration
)
377 Analyze_Entry_Or_Subprogram_Contract
378 (Subp_Id
=> Defining_Entity
(Decl
),
379 Freeze_Id
=> Freeze_Id
);
381 -- Entry or subprogram bodies
383 elsif Nkind_In
(Decl
, N_Entry_Body
, N_Subprogram_Body
) then
384 Analyze_Entry_Or_Subprogram_Body_Contract
(Defining_Entity
(Decl
));
388 elsif Nkind
(Decl
) = N_Object_Declaration
then
389 Analyze_Object_Contract
390 (Obj_Id
=> Defining_Entity
(Decl
),
391 Freeze_Id
=> Freeze_Id
);
395 elsif Nkind_In
(Decl
, N_Protected_Type_Declaration
,
396 N_Single_Protected_Declaration
)
398 Analyze_Protected_Contract
(Defining_Entity
(Decl
));
400 -- Subprogram body stubs
402 elsif Nkind
(Decl
) = N_Subprogram_Body_Stub
then
403 Analyze_Subprogram_Body_Stub_Contract
(Defining_Entity
(Decl
));
407 elsif Nkind_In
(Decl
, N_Single_Task_Declaration
,
408 N_Task_Type_Declaration
)
410 Analyze_Task_Contract
(Defining_Entity
(Decl
));
415 end Analyze_Contracts
;
417 -----------------------------------------------
418 -- Analyze_Entry_Or_Subprogram_Body_Contract --
419 -----------------------------------------------
421 procedure Analyze_Entry_Or_Subprogram_Body_Contract
(Body_Id
: Entity_Id
) is
422 Body_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Body_Id
);
423 Items
: constant Node_Id
:= Contract
(Body_Id
);
424 Spec_Id
: constant Entity_Id
:= Unique_Defining_Entity
(Body_Decl
);
425 Mode
: SPARK_Mode_Type
;
428 -- When a subprogram body declaration is illegal, its defining entity is
429 -- left unanalyzed. There is nothing left to do in this case because the
430 -- body lacks a contract, or even a proper Ekind.
432 if Ekind
(Body_Id
) = E_Void
then
435 -- Do not analyze a contract multiple times
437 elsif Present
(Items
) then
438 if Analyzed
(Items
) then
441 Set_Analyzed
(Items
);
445 -- Due to the timing of contract analysis, delayed pragmas may be
446 -- subject to the wrong SPARK_Mode, usually that of the enclosing
447 -- context. To remedy this, restore the original SPARK_Mode of the
448 -- related subprogram body.
450 Save_SPARK_Mode_And_Set
(Body_Id
, Mode
);
452 -- Ensure that the contract cases or postconditions mention 'Result or
453 -- define a post-state.
455 Check_Result_And_Post_State
(Body_Id
);
457 -- A stand-alone nonvolatile function body cannot have an effectively
458 -- volatile formal parameter or return type (SPARK RM 7.1.3(9)). This
459 -- check is relevant only when SPARK_Mode is on, as it is not a standard
460 -- legality rule. The check is performed here because Volatile_Function
461 -- is processed after the analysis of the related subprogram body.
464 and then Ekind_In
(Body_Id
, E_Function
, E_Generic_Function
)
465 and then not Is_Volatile_Function
(Body_Id
)
467 Check_Nonvolatile_Function_Profile
(Body_Id
);
470 -- Restore the SPARK_Mode of the enclosing context after all delayed
471 -- pragmas have been analyzed.
473 Restore_SPARK_Mode
(Mode
);
475 -- Capture all global references in a generic subprogram body now that
476 -- the contract has been analyzed.
478 if Is_Generic_Declaration_Or_Body
(Body_Decl
) then
479 Save_Global_References_In_Contract
480 (Templ
=> Original_Node
(Body_Decl
),
484 -- Deal with preconditions, [refined] postconditions, Contract_Cases,
485 -- invariants and predicates associated with body and its spec. Do not
486 -- expand the contract of subprogram body stubs.
488 if Nkind
(Body_Decl
) = N_Subprogram_Body
then
489 Expand_Subprogram_Contract
(Body_Id
);
491 end Analyze_Entry_Or_Subprogram_Body_Contract
;
493 ------------------------------------------
494 -- Analyze_Entry_Or_Subprogram_Contract --
495 ------------------------------------------
497 procedure Analyze_Entry_Or_Subprogram_Contract
498 (Subp_Id
: Entity_Id
;
499 Freeze_Id
: Entity_Id
:= Empty
)
501 Items
: constant Node_Id
:= Contract
(Subp_Id
);
502 Subp_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Subp_Id
);
504 Skip_Assert_Exprs
: constant Boolean :=
505 Ekind_In
(Subp_Id
, E_Entry
, E_Entry_Family
)
506 and then not ASIS_Mode
507 and then not GNATprove_Mode
;
509 Depends
: Node_Id
:= Empty
;
510 Global
: Node_Id
:= Empty
;
511 Mode
: SPARK_Mode_Type
;
516 -- Do not analyze a contract multiple times
518 if Present
(Items
) then
519 if Analyzed
(Items
) then
522 Set_Analyzed
(Items
);
526 -- Due to the timing of contract analysis, delayed pragmas may be
527 -- subject to the wrong SPARK_Mode, usually that of the enclosing
528 -- context. To remedy this, restore the original SPARK_Mode of the
529 -- related subprogram body.
531 Save_SPARK_Mode_And_Set
(Subp_Id
, Mode
);
533 -- All subprograms carry a contract, but for some it is not significant
534 -- and should not be processed.
536 if not Has_Significant_Contract
(Subp_Id
) then
539 elsif Present
(Items
) then
541 -- Do not analyze the pre/postconditions of an entry declaration
542 -- unless annotating the original tree for ASIS or GNATprove. The
543 -- real analysis occurs when the pre/postconditons are relocated to
544 -- the contract wrapper procedure (see Build_Contract_Wrapper).
546 if Skip_Assert_Exprs
then
549 -- Otherwise analyze the pre/postconditions
552 Prag
:= Pre_Post_Conditions
(Items
);
553 while Present
(Prag
) loop
554 Analyze_Pre_Post_Condition_In_Decl_Part
(Prag
, Freeze_Id
);
555 Prag
:= Next_Pragma
(Prag
);
559 -- Analyze contract-cases and test-cases
561 Prag
:= Contract_Test_Cases
(Items
);
562 while Present
(Prag
) loop
563 Prag_Nam
:= Pragma_Name
(Prag
);
565 if Prag_Nam
= Name_Contract_Cases
then
567 -- Do not analyze the contract cases of an entry declaration
568 -- unless annotating the original tree for ASIS or GNATprove.
569 -- The real analysis occurs when the contract cases are moved
570 -- to the contract wrapper procedure (Build_Contract_Wrapper).
572 if Skip_Assert_Exprs
then
575 -- Otherwise analyze the contract cases
578 Analyze_Contract_Cases_In_Decl_Part
(Prag
, Freeze_Id
);
581 pragma Assert
(Prag_Nam
= Name_Test_Case
);
582 Analyze_Test_Case_In_Decl_Part
(Prag
);
585 Prag
:= Next_Pragma
(Prag
);
588 -- Analyze classification pragmas
590 Prag
:= Classifications
(Items
);
591 while Present
(Prag
) loop
592 Prag_Nam
:= Pragma_Name
(Prag
);
594 if Prag_Nam
= Name_Depends
then
597 elsif Prag_Nam
= Name_Global
then
601 Prag
:= Next_Pragma
(Prag
);
604 -- Analyze Global first, as Depends may mention items classified in
605 -- the global categorization.
607 if Present
(Global
) then
608 Analyze_Global_In_Decl_Part
(Global
);
611 -- Depends must be analyzed after Global in order to see the modes of
614 if Present
(Depends
) then
615 Analyze_Depends_In_Decl_Part
(Depends
);
618 -- Ensure that the contract cases or postconditions mention 'Result
619 -- or define a post-state.
621 Check_Result_And_Post_State
(Subp_Id
);
624 -- A nonvolatile function cannot have an effectively volatile formal
625 -- parameter or return type (SPARK RM 7.1.3(9)). This check is relevant
626 -- only when SPARK_Mode is on, as it is not a standard legality rule.
627 -- The check is performed here because pragma Volatile_Function is
628 -- processed after the analysis of the related subprogram declaration.
631 and then Ekind_In
(Subp_Id
, E_Function
, E_Generic_Function
)
632 and then not Is_Volatile_Function
(Subp_Id
)
634 Check_Nonvolatile_Function_Profile
(Subp_Id
);
637 -- Restore the SPARK_Mode of the enclosing context after all delayed
638 -- pragmas have been analyzed.
640 Restore_SPARK_Mode
(Mode
);
642 -- Capture all global references in a generic subprogram now that the
643 -- contract has been analyzed.
645 if Is_Generic_Declaration_Or_Body
(Subp_Decl
) then
646 Save_Global_References_In_Contract
647 (Templ
=> Original_Node
(Subp_Decl
),
650 end Analyze_Entry_Or_Subprogram_Contract
;
652 -----------------------------
653 -- Analyze_Object_Contract --
654 -----------------------------
656 procedure Analyze_Object_Contract
658 Freeze_Id
: Entity_Id
:= Empty
)
660 Obj_Typ
: constant Entity_Id
:= Etype
(Obj_Id
);
661 AR_Val
: Boolean := False;
662 AW_Val
: Boolean := False;
663 ER_Val
: Boolean := False;
664 EW_Val
: Boolean := False;
666 Mode
: SPARK_Mode_Type
;
669 Restore_Mode
: Boolean := False;
670 Seen
: Boolean := False;
673 -- The loop parameter in an element iterator over a formal container
674 -- is declared with an object declaration, but no contracts apply.
676 if Ekind
(Obj_Id
) = E_Loop_Parameter
then
680 -- Do not analyze a contract multiple times
682 Items
:= Contract
(Obj_Id
);
684 if Present
(Items
) then
685 if Analyzed
(Items
) then
688 Set_Analyzed
(Items
);
692 -- The anonymous object created for a single concurrent type inherits
693 -- the SPARK_Mode from the type. Due to the timing of contract analysis,
694 -- delayed pragmas may be subject to the wrong SPARK_Mode, usually that
695 -- of the enclosing context. To remedy this, restore the original mode
696 -- of the related anonymous object.
698 if Is_Single_Concurrent_Object
(Obj_Id
)
699 and then Present
(SPARK_Pragma
(Obj_Id
))
701 Restore_Mode
:= True;
702 Save_SPARK_Mode_And_Set
(Obj_Id
, Mode
);
705 -- Constant-related checks
707 if Ekind
(Obj_Id
) = E_Constant
then
709 -- Analyze indicator Part_Of
711 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Part_Of
);
713 -- Check whether the lack of indicator Part_Of agrees with the
714 -- placement of the constant with respect to the state space.
717 Check_Missing_Part_Of
(Obj_Id
);
720 -- A constant cannot be effectively volatile (SPARK RM 7.1.3(4)).
721 -- This check is relevant only when SPARK_Mode is on, as it is not
722 -- a standard Ada legality rule. Internally-generated constants that
723 -- map generic formals to actuals in instantiations are allowed to
727 and then Comes_From_Source
(Obj_Id
)
728 and then Is_Effectively_Volatile
(Obj_Id
)
729 and then No
(Corresponding_Generic_Association
(Parent
(Obj_Id
)))
731 Error_Msg_N
("constant cannot be volatile", Obj_Id
);
734 -- Variable-related checks
736 else pragma Assert
(Ekind
(Obj_Id
) = E_Variable
);
738 -- Analyze all external properties
740 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Async_Readers
);
742 if Present
(Prag
) then
743 Analyze_External_Property_In_Decl_Part
(Prag
, AR_Val
);
747 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Async_Writers
);
749 if Present
(Prag
) then
750 Analyze_External_Property_In_Decl_Part
(Prag
, AW_Val
);
754 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Effective_Reads
);
756 if Present
(Prag
) then
757 Analyze_External_Property_In_Decl_Part
(Prag
, ER_Val
);
761 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Effective_Writes
);
763 if Present
(Prag
) then
764 Analyze_External_Property_In_Decl_Part
(Prag
, EW_Val
);
768 -- Verify the mutual interaction of the various external properties
771 Check_External_Properties
(Obj_Id
, AR_Val
, AW_Val
, ER_Val
, EW_Val
);
774 -- The anonymous object created for a single concurrent type carries
775 -- pragmas Depends and Globat of the type.
777 if Is_Single_Concurrent_Object
(Obj_Id
) then
779 -- Analyze Global first, as Depends may mention items classified
780 -- in the global categorization.
782 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Global
);
784 if Present
(Prag
) then
785 Analyze_Global_In_Decl_Part
(Prag
);
788 -- Depends must be analyzed after Global in order to see the modes
789 -- of all global items.
791 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Depends
);
793 if Present
(Prag
) then
794 Analyze_Depends_In_Decl_Part
(Prag
);
798 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Part_Of
);
800 -- Analyze indicator Part_Of
802 if Present
(Prag
) then
803 Analyze_Part_Of_In_Decl_Part
(Prag
, Freeze_Id
);
805 -- The variable is a constituent of a single protected/task type
806 -- and behaves as a component of the type. Verify that references
807 -- to the variable occur within the definition or body of the type
810 if Present
(Encapsulating_State
(Obj_Id
))
811 and then Is_Single_Concurrent_Object
812 (Encapsulating_State
(Obj_Id
))
813 and then Present
(Part_Of_References
(Obj_Id
))
815 Ref_Elmt
:= First_Elmt
(Part_Of_References
(Obj_Id
));
816 while Present
(Ref_Elmt
) loop
817 Check_Part_Of_Reference
(Obj_Id
, Node
(Ref_Elmt
));
818 Next_Elmt
(Ref_Elmt
);
822 -- Otherwise check whether the lack of indicator Part_Of agrees with
823 -- the placement of the variable with respect to the state space.
826 Check_Missing_Part_Of
(Obj_Id
);
829 -- The following checks are relevant only when SPARK_Mode is on, as
830 -- they are not standard Ada legality rules. Internally generated
831 -- temporaries are ignored.
833 if SPARK_Mode
= On
and then Comes_From_Source
(Obj_Id
) then
834 if Is_Effectively_Volatile
(Obj_Id
) then
836 -- The declaration of an effectively volatile object must
837 -- appear at the library level (SPARK RM 7.1.3(3), C.6(6)).
839 if not Is_Library_Level_Entity
(Obj_Id
) then
841 ("volatile variable & must be declared at library level",
844 -- An object of a discriminated type cannot be effectively
845 -- volatile except for protected objects (SPARK RM 7.1.3(5)).
847 elsif Has_Discriminants
(Obj_Typ
)
848 and then not Is_Protected_Type
(Obj_Typ
)
851 ("discriminated object & cannot be volatile", Obj_Id
);
853 -- An object of a tagged type cannot be effectively volatile
854 -- (SPARK RM C.6(5)).
856 elsif Is_Tagged_Type
(Obj_Typ
) then
857 Error_Msg_N
("tagged object & cannot be volatile", Obj_Id
);
860 -- The object is not effectively volatile
863 -- A non-effectively volatile object cannot have effectively
864 -- volatile components (SPARK RM 7.1.3(6)).
866 if not Is_Effectively_Volatile
(Obj_Id
)
867 and then Has_Volatile_Component
(Obj_Typ
)
870 ("non-volatile object & cannot have volatile components",
879 if Comes_From_Source
(Obj_Id
) and then Is_Ghost_Entity
(Obj_Id
) then
881 -- A Ghost object cannot be of a type that yields a synchronized
882 -- object (SPARK RM 6.9(19)).
884 if Yields_Synchronized_Object
(Obj_Typ
) then
885 Error_Msg_N
("ghost object & cannot be synchronized", Obj_Id
);
887 -- A Ghost object cannot be effectively volatile (SPARK RM 6.9(7) and
888 -- SPARK RM 6.9(19)).
890 elsif Is_Effectively_Volatile
(Obj_Id
) then
891 Error_Msg_N
("ghost object & cannot be volatile", Obj_Id
);
893 -- A Ghost object cannot be imported or exported (SPARK RM 6.9(7)).
894 -- One exception to this is the object that represents the dispatch
895 -- table of a Ghost tagged type, as the symbol needs to be exported.
897 elsif Is_Exported
(Obj_Id
) then
898 Error_Msg_N
("ghost object & cannot be exported", Obj_Id
);
900 elsif Is_Imported
(Obj_Id
) then
901 Error_Msg_N
("ghost object & cannot be imported", Obj_Id
);
905 -- Restore the SPARK_Mode of the enclosing context after all delayed
906 -- pragmas have been analyzed.
909 Restore_SPARK_Mode
(Mode
);
911 end Analyze_Object_Contract
;
913 -----------------------------------
914 -- Analyze_Package_Body_Contract --
915 -----------------------------------
917 procedure Analyze_Package_Body_Contract
918 (Body_Id
: Entity_Id
;
919 Freeze_Id
: Entity_Id
:= Empty
)
921 Body_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Body_Id
);
922 Items
: constant Node_Id
:= Contract
(Body_Id
);
923 Spec_Id
: constant Entity_Id
:= Spec_Entity
(Body_Id
);
924 Mode
: SPARK_Mode_Type
;
928 -- Do not analyze a contract multiple times
930 if Present
(Items
) then
931 if Analyzed
(Items
) then
934 Set_Analyzed
(Items
);
938 -- Due to the timing of contract analysis, delayed pragmas may be
939 -- subject to the wrong SPARK_Mode, usually that of the enclosing
940 -- context. To remedy this, restore the original SPARK_Mode of the
941 -- related package body.
943 Save_SPARK_Mode_And_Set
(Body_Id
, Mode
);
945 Ref_State
:= Get_Pragma
(Body_Id
, Pragma_Refined_State
);
947 -- The analysis of pragma Refined_State detects whether the spec has
948 -- abstract states available for refinement.
950 if Present
(Ref_State
) then
951 Analyze_Refined_State_In_Decl_Part
(Ref_State
, Freeze_Id
);
954 -- Restore the SPARK_Mode of the enclosing context after all delayed
955 -- pragmas have been analyzed.
957 Restore_SPARK_Mode
(Mode
);
959 -- Capture all global references in a generic package body now that the
960 -- contract has been analyzed.
962 if Is_Generic_Declaration_Or_Body
(Body_Decl
) then
963 Save_Global_References_In_Contract
964 (Templ
=> Original_Node
(Body_Decl
),
967 end Analyze_Package_Body_Contract
;
969 ------------------------------
970 -- Analyze_Package_Contract --
971 ------------------------------
973 procedure Analyze_Package_Contract
(Pack_Id
: Entity_Id
) is
974 Items
: constant Node_Id
:= Contract
(Pack_Id
);
975 Pack_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Pack_Id
);
976 Init
: Node_Id
:= Empty
;
977 Init_Cond
: Node_Id
:= Empty
;
978 Mode
: SPARK_Mode_Type
;
983 -- Do not analyze a contract multiple times
985 if Present
(Items
) then
986 if Analyzed
(Items
) then
989 Set_Analyzed
(Items
);
993 -- Due to the timing of contract analysis, delayed pragmas may be
994 -- subject to the wrong SPARK_Mode, usually that of the enclosing
995 -- context. To remedy this, restore the original SPARK_Mode of the
998 Save_SPARK_Mode_And_Set
(Pack_Id
, Mode
);
1000 if Present
(Items
) then
1002 -- Locate and store pragmas Initial_Condition and Initializes, since
1003 -- their order of analysis matters.
1005 Prag
:= Classifications
(Items
);
1006 while Present
(Prag
) loop
1007 Prag_Nam
:= Pragma_Name
(Prag
);
1009 if Prag_Nam
= Name_Initial_Condition
then
1012 elsif Prag_Nam
= Name_Initializes
then
1016 Prag
:= Next_Pragma
(Prag
);
1019 -- Analyze the initialization-related pragmas. Initializes must come
1020 -- before Initial_Condition due to item dependencies.
1022 if Present
(Init
) then
1023 Analyze_Initializes_In_Decl_Part
(Init
);
1026 if Present
(Init_Cond
) then
1027 Analyze_Initial_Condition_In_Decl_Part
(Init_Cond
);
1031 -- Check whether the lack of indicator Part_Of agrees with the placement
1032 -- of the package instantiation with respect to the state space.
1034 if Is_Generic_Instance
(Pack_Id
) then
1035 Prag
:= Get_Pragma
(Pack_Id
, Pragma_Part_Of
);
1038 Check_Missing_Part_Of
(Pack_Id
);
1042 -- Restore the SPARK_Mode of the enclosing context after all delayed
1043 -- pragmas have been analyzed.
1045 Restore_SPARK_Mode
(Mode
);
1047 -- Capture all global references in a generic package now that the
1048 -- contract has been analyzed.
1050 if Is_Generic_Declaration_Or_Body
(Pack_Decl
) then
1051 Save_Global_References_In_Contract
1052 (Templ
=> Original_Node
(Pack_Decl
),
1055 end Analyze_Package_Contract
;
1057 --------------------------------
1058 -- Analyze_Previous_Contracts --
1059 --------------------------------
1061 procedure Analyze_Previous_Contracts
(Body_Decl
: Node_Id
) is
1062 Body_Id
: constant Entity_Id
:= Defining_Entity
(Body_Decl
);
1066 -- A body that is in the process of being inlined appears from source,
1067 -- but carries name _parent. Such a body does not cause "freezing" of
1070 if Chars
(Body_Id
) = Name_uParent
then
1074 -- Climb the parent chain looking for an enclosing package body. Do not
1075 -- use the scope stack, as a body uses the entity of its corresponding
1078 Par
:= Parent
(Body_Decl
);
1079 while Present
(Par
) loop
1080 if Nkind
(Par
) = N_Package_Body
then
1081 Analyze_Package_Body_Contract
1082 (Body_Id
=> Defining_Entity
(Par
),
1083 Freeze_Id
=> Defining_Entity
(Body_Decl
));
1088 Par
:= Parent
(Par
);
1091 -- Analyze the contracts of all eligible construct up to the body which
1092 -- caused the "freezing".
1094 if Is_List_Member
(Body_Decl
) then
1096 (L
=> List_Containing
(Body_Decl
),
1097 Freeze_Nod
=> Body_Decl
,
1098 Freeze_Id
=> Body_Id
);
1100 end Analyze_Previous_Contracts
;
1102 --------------------------------
1103 -- Analyze_Protected_Contract --
1104 --------------------------------
1106 procedure Analyze_Protected_Contract
(Prot_Id
: Entity_Id
) is
1107 Items
: constant Node_Id
:= Contract
(Prot_Id
);
1110 -- Do not analyze a contract multiple times
1112 if Present
(Items
) then
1113 if Analyzed
(Items
) then
1116 Set_Analyzed
(Items
);
1119 end Analyze_Protected_Contract
;
1121 -------------------------------------------
1122 -- Analyze_Subprogram_Body_Stub_Contract --
1123 -------------------------------------------
1125 procedure Analyze_Subprogram_Body_Stub_Contract
(Stub_Id
: Entity_Id
) is
1126 Stub_Decl
: constant Node_Id
:= Parent
(Parent
(Stub_Id
));
1127 Spec_Id
: constant Entity_Id
:= Corresponding_Spec_Of_Stub
(Stub_Decl
);
1130 -- A subprogram body stub may act as its own spec or as the completion
1131 -- of a previous declaration. Depending on the context, the contract of
1132 -- the stub may contain two sets of pragmas.
1134 -- The stub is a completion, the applicable pragmas are:
1138 if Present
(Spec_Id
) then
1139 Analyze_Entry_Or_Subprogram_Body_Contract
(Stub_Id
);
1141 -- The stub acts as its own spec, the applicable pragmas are:
1150 Analyze_Entry_Or_Subprogram_Contract
(Stub_Id
);
1152 end Analyze_Subprogram_Body_Stub_Contract
;
1154 ---------------------------
1155 -- Analyze_Task_Contract --
1156 ---------------------------
1158 procedure Analyze_Task_Contract
(Task_Id
: Entity_Id
) is
1159 Items
: constant Node_Id
:= Contract
(Task_Id
);
1160 Mode
: SPARK_Mode_Type
;
1164 -- Do not analyze a contract multiple times
1166 if Present
(Items
) then
1167 if Analyzed
(Items
) then
1170 Set_Analyzed
(Items
);
1174 -- Due to the timing of contract analysis, delayed pragmas may be
1175 -- subject to the wrong SPARK_Mode, usually that of the enclosing
1176 -- context. To remedy this, restore the original SPARK_Mode of the
1177 -- related task unit.
1179 Save_SPARK_Mode_And_Set
(Task_Id
, Mode
);
1181 -- Analyze Global first, as Depends may mention items classified in the
1182 -- global categorization.
1184 Prag
:= Get_Pragma
(Task_Id
, Pragma_Global
);
1186 if Present
(Prag
) then
1187 Analyze_Global_In_Decl_Part
(Prag
);
1190 -- Depends must be analyzed after Global in order to see the modes of
1191 -- all global items.
1193 Prag
:= Get_Pragma
(Task_Id
, Pragma_Depends
);
1195 if Present
(Prag
) then
1196 Analyze_Depends_In_Decl_Part
(Prag
);
1199 -- Restore the SPARK_Mode of the enclosing context after all delayed
1200 -- pragmas have been analyzed.
1202 Restore_SPARK_Mode
(Mode
);
1203 end Analyze_Task_Contract
;
1205 -----------------------------
1206 -- Create_Generic_Contract --
1207 -----------------------------
1209 procedure Create_Generic_Contract
(Unit
: Node_Id
) is
1210 Templ
: constant Node_Id
:= Original_Node
(Unit
);
1211 Templ_Id
: constant Entity_Id
:= Defining_Entity
(Templ
);
1213 procedure Add_Generic_Contract_Pragma
(Prag
: Node_Id
);
1214 -- Add a single contract-related source pragma Prag to the contract of
1215 -- generic template Templ_Id.
1217 ---------------------------------
1218 -- Add_Generic_Contract_Pragma --
1219 ---------------------------------
1221 procedure Add_Generic_Contract_Pragma
(Prag
: Node_Id
) is
1222 Prag_Templ
: Node_Id
;
1225 -- Mark the pragma to prevent the premature capture of global
1226 -- references when capturing global references of the context
1227 -- (see Save_References_In_Pragma).
1229 Set_Is_Generic_Contract_Pragma
(Prag
);
1231 -- Pragmas that apply to a generic subprogram declaration are not
1232 -- part of the semantic structure of the generic template:
1235 -- procedure Example (Formal : Integer);
1236 -- pragma Precondition (Formal > 0);
1238 -- Create a generic template for such pragmas and link the template
1239 -- of the pragma with the generic template.
1241 if Nkind
(Templ
) = N_Generic_Subprogram_Declaration
then
1243 (Prag
, Copy_Generic_Node
(Prag
, Empty
, Instantiating
=> False));
1244 Prag_Templ
:= Original_Node
(Prag
);
1246 Set_Is_Generic_Contract_Pragma
(Prag_Templ
);
1247 Add_Contract_Item
(Prag_Templ
, Templ_Id
);
1249 -- Otherwise link the pragma with the generic template
1252 Add_Contract_Item
(Prag
, Templ_Id
);
1254 end Add_Generic_Contract_Pragma
;
1258 Context
: constant Node_Id
:= Parent
(Unit
);
1259 Decl
: Node_Id
:= Empty
;
1261 -- Start of processing for Create_Generic_Contract
1264 -- A generic package declaration carries contract-related source pragmas
1265 -- in its visible declarations.
1267 if Nkind
(Templ
) = N_Generic_Package_Declaration
then
1268 Set_Ekind
(Templ_Id
, E_Generic_Package
);
1270 if Present
(Visible_Declarations
(Specification
(Templ
))) then
1271 Decl
:= First
(Visible_Declarations
(Specification
(Templ
)));
1274 -- A generic package body carries contract-related source pragmas in its
1277 elsif Nkind
(Templ
) = N_Package_Body
then
1278 Set_Ekind
(Templ_Id
, E_Package_Body
);
1280 if Present
(Declarations
(Templ
)) then
1281 Decl
:= First
(Declarations
(Templ
));
1284 -- Generic subprogram declaration
1286 elsif Nkind
(Templ
) = N_Generic_Subprogram_Declaration
then
1287 if Nkind
(Specification
(Templ
)) = N_Function_Specification
then
1288 Set_Ekind
(Templ_Id
, E_Generic_Function
);
1290 Set_Ekind
(Templ_Id
, E_Generic_Procedure
);
1293 -- When the generic subprogram acts as a compilation unit, inspect
1294 -- the Pragmas_After list for contract-related source pragmas.
1296 if Nkind
(Context
) = N_Compilation_Unit
then
1297 if Present
(Aux_Decls_Node
(Context
))
1298 and then Present
(Pragmas_After
(Aux_Decls_Node
(Context
)))
1300 Decl
:= First
(Pragmas_After
(Aux_Decls_Node
(Context
)));
1303 -- Otherwise inspect the successive declarations for contract-related
1307 Decl
:= Next
(Unit
);
1310 -- A generic subprogram body carries contract-related source pragmas in
1311 -- its declarations.
1313 elsif Nkind
(Templ
) = N_Subprogram_Body
then
1314 Set_Ekind
(Templ_Id
, E_Subprogram_Body
);
1316 if Present
(Declarations
(Templ
)) then
1317 Decl
:= First
(Declarations
(Templ
));
1321 -- Inspect the relevant declarations looking for contract-related source
1322 -- pragmas and add them to the contract of the generic unit.
1324 while Present
(Decl
) loop
1325 if Comes_From_Source
(Decl
) then
1326 if Nkind
(Decl
) = N_Pragma
then
1328 -- The source pragma is a contract annotation
1330 if Is_Contract_Annotation
(Decl
) then
1331 Add_Generic_Contract_Pragma
(Decl
);
1334 -- The region where a contract-related source pragma may appear
1335 -- ends with the first source non-pragma declaration or statement.
1344 end Create_Generic_Contract
;
1346 --------------------------------
1347 -- Expand_Subprogram_Contract --
1348 --------------------------------
1350 procedure Expand_Subprogram_Contract
(Body_Id
: Entity_Id
) is
1351 Body_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Body_Id
);
1352 Spec_Id
: constant Entity_Id
:= Corresponding_Spec
(Body_Decl
);
1354 procedure Add_Invariant_And_Predicate_Checks
1355 (Subp_Id
: Entity_Id
;
1356 Stmts
: in out List_Id
;
1357 Result
: out Node_Id
);
1358 -- Process the result of function Subp_Id (if applicable) and all its
1359 -- formals. Add invariant and predicate checks where applicable. The
1360 -- routine appends all the checks to list Stmts. If Subp_Id denotes a
1361 -- function, Result contains the entity of parameter _Result, to be
1362 -- used in the creation of procedure _Postconditions.
1364 procedure Append_Enabled_Item
(Item
: Node_Id
; List
: in out List_Id
);
1365 -- Append a node to a list. If there is no list, create a new one. When
1366 -- the item denotes a pragma, it is added to the list only when it is
1369 procedure Build_Postconditions_Procedure
1370 (Subp_Id
: Entity_Id
;
1372 Result
: Entity_Id
);
1373 -- Create the body of procedure _Postconditions which handles various
1374 -- assertion actions on exit from subprogram Subp_Id. Stmts is the list
1375 -- of statements to be checked on exit. Parameter Result is the entity
1376 -- of parameter _Result when Subp_Id denotes a function.
1378 procedure Process_Contract_Cases
(Stmts
: in out List_Id
);
1379 -- Process pragma Contract_Cases. This routine prepends items to the
1380 -- body declarations and appends items to list Stmts.
1382 procedure Process_Postconditions
(Stmts
: in out List_Id
);
1383 -- Collect all [inherited] spec and body postconditions and accumulate
1384 -- their pragma Check equivalents in list Stmts.
1386 procedure Process_Preconditions
;
1387 -- Collect all [inherited] spec and body preconditions and prepend their
1388 -- pragma Check equivalents to the declarations of the body.
1390 ----------------------------------------
1391 -- Add_Invariant_And_Predicate_Checks --
1392 ----------------------------------------
1394 procedure Add_Invariant_And_Predicate_Checks
1395 (Subp_Id
: Entity_Id
;
1396 Stmts
: in out List_Id
;
1397 Result
: out Node_Id
)
1399 procedure Add_Invariant_Access_Checks
(Id
: Entity_Id
);
1400 -- Id denotes the return value of a function or a formal parameter.
1401 -- Add an invariant check if the type of Id is access to a type with
1402 -- invariants. The routine appends the generated code to Stmts.
1404 function Invariant_Checks_OK
(Typ
: Entity_Id
) return Boolean;
1405 -- Determine whether type Typ can benefit from invariant checks. To
1406 -- qualify, the type must have a non-null invariant procedure and
1407 -- subprogram Subp_Id must appear visible from the point of view of
1410 ---------------------------------
1411 -- Add_Invariant_Access_Checks --
1412 ---------------------------------
1414 procedure Add_Invariant_Access_Checks
(Id
: Entity_Id
) is
1415 Loc
: constant Source_Ptr
:= Sloc
(Body_Decl
);
1422 if Is_Access_Type
(Typ
) and then not Is_Access_Constant
(Typ
) then
1423 Typ
:= Designated_Type
(Typ
);
1425 if Invariant_Checks_OK
(Typ
) then
1427 Make_Explicit_Dereference
(Loc
,
1428 Prefix
=> New_Occurrence_Of
(Id
, Loc
));
1429 Set_Etype
(Ref
, Typ
);
1432 -- if <Id> /= null then
1433 -- <invariant_call (<Ref>)>
1438 Make_If_Statement
(Loc
,
1441 Left_Opnd
=> New_Occurrence_Of
(Id
, Loc
),
1442 Right_Opnd
=> Make_Null
(Loc
)),
1443 Then_Statements
=> New_List
(
1444 Make_Invariant_Call
(Ref
))),
1448 end Add_Invariant_Access_Checks
;
1450 -------------------------
1451 -- Invariant_Checks_OK --
1452 -------------------------
1454 function Invariant_Checks_OK
(Typ
: Entity_Id
) return Boolean is
1455 function Has_Public_Visibility_Of_Subprogram
return Boolean;
1456 -- Determine whether type Typ has public visibility of subprogram
1459 -----------------------------------------
1460 -- Has_Public_Visibility_Of_Subprogram --
1461 -----------------------------------------
1463 function Has_Public_Visibility_Of_Subprogram
return Boolean is
1464 Subp_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Subp_Id
);
1467 -- An Initialization procedure must be considered visible even
1468 -- though it is internally generated.
1470 if Is_Init_Proc
(Defining_Entity
(Subp_Decl
)) then
1473 elsif Ekind
(Scope
(Typ
)) /= E_Package
then
1476 -- Internally generated code is never publicly visible except
1477 -- for a subprogram that is the implementation of an expression
1478 -- function. In that case the visibility is determined by the
1481 elsif not Comes_From_Source
(Subp_Decl
)
1483 (Nkind
(Original_Node
(Subp_Decl
)) /= N_Expression_Function
1485 Comes_From_Source
(Defining_Entity
(Subp_Decl
)))
1489 -- Determine whether the subprogram is declared in the visible
1490 -- declarations of the package containing the type.
1493 return List_Containing
(Subp_Decl
) =
1494 Visible_Declarations
1495 (Specification
(Unit_Declaration_Node
(Scope
(Typ
))));
1497 end Has_Public_Visibility_Of_Subprogram
;
1499 -- Start of processing for Invariant_Checks_OK
1503 Has_Invariants
(Typ
)
1504 and then Present
(Invariant_Procedure
(Typ
))
1505 and then not Has_Null_Body
(Invariant_Procedure
(Typ
))
1506 and then Has_Public_Visibility_Of_Subprogram
;
1507 end Invariant_Checks_OK
;
1511 Loc
: constant Source_Ptr
:= Sloc
(Body_Decl
);
1512 -- Source location of subprogram body contract
1517 -- Start of processing for Add_Invariant_And_Predicate_Checks
1522 -- Process the result of a function
1524 if Ekind
(Subp_Id
) = E_Function
then
1525 Typ
:= Etype
(Subp_Id
);
1527 -- Generate _Result which is used in procedure _Postconditions to
1528 -- verify the return value.
1530 Result
:= Make_Defining_Identifier
(Loc
, Name_uResult
);
1531 Set_Etype
(Result
, Typ
);
1533 -- Add an invariant check when the return type has invariants and
1534 -- the related function is visible to the outside.
1536 if Invariant_Checks_OK
(Typ
) then
1539 Make_Invariant_Call
(New_Occurrence_Of
(Result
, Loc
)),
1543 -- Add an invariant check when the return type is an access to a
1544 -- type with invariants.
1546 Add_Invariant_Access_Checks
(Result
);
1549 -- Add invariant and predicates for all formals that qualify
1551 Formal
:= First_Formal
(Subp_Id
);
1552 while Present
(Formal
) loop
1553 Typ
:= Etype
(Formal
);
1555 if Ekind
(Formal
) /= E_In_Parameter
1556 or else Is_Access_Type
(Typ
)
1558 if Invariant_Checks_OK
(Typ
) then
1561 Make_Invariant_Call
(New_Occurrence_Of
(Formal
, Loc
)),
1565 Add_Invariant_Access_Checks
(Formal
);
1567 -- Note: we used to add predicate checks for OUT and IN OUT
1568 -- formals here, but that was misguided, since such checks are
1569 -- performed on the caller side, based on the predicate of the
1570 -- actual, rather than the predicate of the formal.
1574 Next_Formal
(Formal
);
1576 end Add_Invariant_And_Predicate_Checks
;
1578 -------------------------
1579 -- Append_Enabled_Item --
1580 -------------------------
1582 procedure Append_Enabled_Item
(Item
: Node_Id
; List
: in out List_Id
) is
1584 -- Do not chain ignored or disabled pragmas
1586 if Nkind
(Item
) = N_Pragma
1587 and then (Is_Ignored
(Item
) or else Is_Disabled
(Item
))
1591 -- Otherwise, add the item
1598 -- If the pragma is a conjunct in a composite postcondition, it
1599 -- has been processed in reverse order. In the postcondition body
1600 -- it must appear before the others.
1602 if Nkind
(Item
) = N_Pragma
1603 and then From_Aspect_Specification
(Item
)
1604 and then Split_PPC
(Item
)
1606 Prepend
(Item
, List
);
1608 Append
(Item
, List
);
1611 end Append_Enabled_Item
;
1613 ------------------------------------
1614 -- Build_Postconditions_Procedure --
1615 ------------------------------------
1617 procedure Build_Postconditions_Procedure
1618 (Subp_Id
: Entity_Id
;
1622 procedure Insert_Before_First_Source_Declaration
(Stmt
: Node_Id
);
1623 -- Insert node Stmt before the first source declaration of the
1624 -- related subprogram's body. If no such declaration exists, Stmt
1625 -- becomes the last declaration.
1627 --------------------------------------------
1628 -- Insert_Before_First_Source_Declaration --
1629 --------------------------------------------
1631 procedure Insert_Before_First_Source_Declaration
(Stmt
: Node_Id
) is
1632 Decls
: constant List_Id
:= Declarations
(Body_Decl
);
1636 -- Inspect the declarations of the related subprogram body looking
1637 -- for the first source declaration.
1639 if Present
(Decls
) then
1640 Decl
:= First
(Decls
);
1641 while Present
(Decl
) loop
1642 if Comes_From_Source
(Decl
) then
1643 Insert_Before
(Decl
, Stmt
);
1650 -- If we get there, then the subprogram body lacks any source
1651 -- declarations. The body of _Postconditions now acts as the
1652 -- last declaration.
1654 Append
(Stmt
, Decls
);
1656 -- Ensure that the body has a declaration list
1659 Set_Declarations
(Body_Decl
, New_List
(Stmt
));
1661 end Insert_Before_First_Source_Declaration
;
1665 Loc
: constant Source_Ptr
:= Sloc
(Body_Decl
);
1666 Params
: List_Id
:= No_List
;
1668 Proc_Decl
: Node_Id
;
1669 Proc_Id
: Entity_Id
;
1670 Proc_Spec
: Node_Id
;
1672 -- Start of processing for Build_Postconditions_Procedure
1675 -- Nothing to do if there are no actions to check on exit
1681 Proc_Id
:= Make_Defining_Identifier
(Loc
, Name_uPostconditions
);
1682 Set_Debug_Info_Needed
(Proc_Id
);
1683 Set_Postconditions_Proc
(Subp_Id
, Proc_Id
);
1685 -- Force the front-end inlining of _Postconditions when generating C
1686 -- code, since its body may have references to itypes defined in the
1687 -- enclosing subprogram, which would cause problems for unnesting
1688 -- routines in the absence of inlining.
1690 if Generate_C_Code
then
1691 Set_Has_Pragma_Inline
(Proc_Id
);
1692 Set_Has_Pragma_Inline_Always
(Proc_Id
);
1693 Set_Is_Inlined
(Proc_Id
);
1696 -- The related subprogram is a function: create the specification of
1697 -- parameter _Result.
1699 if Present
(Result
) then
1700 Params
:= New_List
(
1701 Make_Parameter_Specification
(Loc
,
1702 Defining_Identifier
=> Result
,
1704 New_Occurrence_Of
(Etype
(Result
), Loc
)));
1708 Make_Procedure_Specification
(Loc
,
1709 Defining_Unit_Name
=> Proc_Id
,
1710 Parameter_Specifications
=> Params
);
1712 Proc_Decl
:= Make_Subprogram_Declaration
(Loc
, Proc_Spec
);
1714 -- Insert _Postconditions before the first source declaration of the
1715 -- body. This ensures that the body will not cause any premature
1716 -- freezing, as it may mention types:
1718 -- procedure Proc (Obj : Array_Typ) is
1719 -- procedure _postconditions is
1722 -- end _postconditions;
1724 -- subtype T is Array_Typ (Obj'First (1) .. Obj'Last (1));
1727 -- In the example above, Obj is of type T but the incorrect placement
1728 -- of _Postconditions will cause a crash in gigi due to an out-of-
1729 -- order reference. The body of _Postconditions must be placed after
1730 -- the declaration of Temp to preserve correct visibility.
1732 Insert_Before_First_Source_Declaration
(Proc_Decl
);
1733 Analyze
(Proc_Decl
);
1735 -- Set an explicit End_Label to override the sloc of the implicit
1736 -- RETURN statement, and prevent it from inheriting the sloc of one
1737 -- the postconditions: this would cause confusing debug info to be
1738 -- produced, interfering with coverage-analysis tools.
1741 Make_Subprogram_Body
(Loc
,
1743 Copy_Subprogram_Spec
(Proc_Spec
),
1744 Declarations
=> Empty_List
,
1745 Handled_Statement_Sequence
=>
1746 Make_Handled_Sequence_Of_Statements
(Loc
,
1747 Statements
=> Stmts
,
1748 End_Label
=> Make_Identifier
(Loc
, Chars
(Proc_Id
))));
1750 Insert_After_And_Analyze
(Proc_Decl
, Proc_Bod
);
1751 end Build_Postconditions_Procedure
;
1753 ----------------------------
1754 -- Process_Contract_Cases --
1755 ----------------------------
1757 procedure Process_Contract_Cases
(Stmts
: in out List_Id
) is
1758 procedure Process_Contract_Cases_For
(Subp_Id
: Entity_Id
);
1759 -- Process pragma Contract_Cases for subprogram Subp_Id
1761 --------------------------------
1762 -- Process_Contract_Cases_For --
1763 --------------------------------
1765 procedure Process_Contract_Cases_For
(Subp_Id
: Entity_Id
) is
1766 Items
: constant Node_Id
:= Contract
(Subp_Id
);
1770 if Present
(Items
) then
1771 Prag
:= Contract_Test_Cases
(Items
);
1772 while Present
(Prag
) loop
1773 if Pragma_Name
(Prag
) = Name_Contract_Cases
then
1774 Expand_Pragma_Contract_Cases
1777 Decls
=> Declarations
(Body_Decl
),
1781 Prag
:= Next_Pragma
(Prag
);
1784 end Process_Contract_Cases_For
;
1786 -- Start of processing for Process_Contract_Cases
1789 Process_Contract_Cases_For
(Body_Id
);
1791 if Present
(Spec_Id
) then
1792 Process_Contract_Cases_For
(Spec_Id
);
1794 end Process_Contract_Cases
;
1796 ----------------------------
1797 -- Process_Postconditions --
1798 ----------------------------
1800 procedure Process_Postconditions
(Stmts
: in out List_Id
) is
1801 procedure Process_Body_Postconditions
(Post_Nam
: Name_Id
);
1802 -- Collect all [refined] postconditions of a specific kind denoted
1803 -- by Post_Nam that belong to the body, and generate pragma Check
1804 -- equivalents in list Stmts.
1806 procedure Process_Spec_Postconditions
;
1807 -- Collect all [inherited] postconditions of the spec, and generate
1808 -- pragma Check equivalents in list Stmts.
1810 ---------------------------------
1811 -- Process_Body_Postconditions --
1812 ---------------------------------
1814 procedure Process_Body_Postconditions
(Post_Nam
: Name_Id
) is
1815 Items
: constant Node_Id
:= Contract
(Body_Id
);
1816 Unit_Decl
: constant Node_Id
:= Parent
(Body_Decl
);
1821 -- Process the contract
1823 if Present
(Items
) then
1824 Prag
:= Pre_Post_Conditions
(Items
);
1825 while Present
(Prag
) loop
1826 if Pragma_Name
(Prag
) = Post_Nam
then
1828 (Item
=> Build_Pragma_Check_Equivalent
(Prag
),
1832 Prag
:= Next_Pragma
(Prag
);
1836 -- The subprogram body being processed is actually the proper body
1837 -- of a stub with a corresponding spec. The subprogram stub may
1838 -- carry a postcondition pragma, in which case it must be taken
1839 -- into account. The pragma appears after the stub.
1841 if Present
(Spec_Id
) and then Nkind
(Unit_Decl
) = N_Subunit
then
1842 Decl
:= Next
(Corresponding_Stub
(Unit_Decl
));
1843 while Present
(Decl
) loop
1845 -- Note that non-matching pragmas are skipped
1847 if Nkind
(Decl
) = N_Pragma
then
1848 if Pragma_Name
(Decl
) = Post_Nam
then
1850 (Item
=> Build_Pragma_Check_Equivalent
(Decl
),
1854 -- Skip internally generated code
1856 elsif not Comes_From_Source
(Decl
) then
1859 -- Postcondition pragmas are usually grouped together. There
1860 -- is no need to inspect the whole declarative list.
1869 end Process_Body_Postconditions
;
1871 ---------------------------------
1872 -- Process_Spec_Postconditions --
1873 ---------------------------------
1875 procedure Process_Spec_Postconditions
is
1876 Subps
: constant Subprogram_List
:=
1877 Inherited_Subprograms
(Spec_Id
);
1880 Subp_Id
: Entity_Id
;
1883 -- Process the contract
1885 Items
:= Contract
(Spec_Id
);
1887 if Present
(Items
) then
1888 Prag
:= Pre_Post_Conditions
(Items
);
1889 while Present
(Prag
) loop
1890 if Pragma_Name
(Prag
) = Name_Postcondition
then
1892 (Item
=> Build_Pragma_Check_Equivalent
(Prag
),
1896 Prag
:= Next_Pragma
(Prag
);
1900 -- Process the contracts of all inherited subprograms, looking for
1901 -- class-wide postconditions.
1903 for Index
in Subps
'Range loop
1904 Subp_Id
:= Subps
(Index
);
1905 Items
:= Contract
(Subp_Id
);
1907 if Present
(Items
) then
1908 Prag
:= Pre_Post_Conditions
(Items
);
1909 while Present
(Prag
) loop
1910 if Pragma_Name
(Prag
) = Name_Postcondition
1911 and then Class_Present
(Prag
)
1915 Build_Pragma_Check_Equivalent
1918 Inher_Id
=> Subp_Id
),
1922 Prag
:= Next_Pragma
(Prag
);
1926 end Process_Spec_Postconditions
;
1928 -- Start of processing for Process_Postconditions
1931 -- The processing of postconditions is done in reverse order (body
1932 -- first) to ensure the following arrangement:
1934 -- <refined postconditions from body>
1935 -- <postconditions from body>
1936 -- <postconditions from spec>
1937 -- <inherited postconditions>
1939 Process_Body_Postconditions
(Name_Refined_Post
);
1940 Process_Body_Postconditions
(Name_Postcondition
);
1942 if Present
(Spec_Id
) then
1943 Process_Spec_Postconditions
;
1945 end Process_Postconditions
;
1947 ---------------------------
1948 -- Process_Preconditions --
1949 ---------------------------
1951 procedure Process_Preconditions
is
1952 Class_Pre
: Node_Id
:= Empty
;
1953 -- The sole [inherited] class-wide precondition pragma that applies
1954 -- to the subprogram.
1956 Insert_Node
: Node_Id
:= Empty
;
1957 -- The insertion node after which all pragma Check equivalents are
1960 function Is_Prologue_Renaming
(Decl
: Node_Id
) return Boolean;
1961 -- Determine whether arbitrary declaration Decl denotes a renaming of
1962 -- a discriminant or protection field _object.
1964 procedure Merge_Preconditions
(From
: Node_Id
; Into
: Node_Id
);
1965 -- Merge two class-wide preconditions by "or else"-ing them. The
1966 -- changes are accumulated in parameter Into. Update the error
1969 procedure Prepend_To_Decls
(Item
: Node_Id
);
1970 -- Prepend a single item to the declarations of the subprogram body
1972 procedure Prepend_To_Decls_Or_Save
(Prag
: Node_Id
);
1973 -- Save a class-wide precondition into Class_Pre, or prepend a normal
1974 -- precondition to the declarations of the body and analyze it.
1976 procedure Process_Inherited_Preconditions
;
1977 -- Collect all inherited class-wide preconditions and merge them into
1978 -- one big precondition to be evaluated as pragma Check.
1980 procedure Process_Preconditions_For
(Subp_Id
: Entity_Id
);
1981 -- Collect all preconditions of subprogram Subp_Id and prepend their
1982 -- pragma Check equivalents to the declarations of the body.
1984 --------------------------
1985 -- Is_Prologue_Renaming --
1986 --------------------------
1988 function Is_Prologue_Renaming
(Decl
: Node_Id
) return Boolean is
1995 if Nkind
(Decl
) = N_Object_Renaming_Declaration
then
1996 Obj
:= Defining_Entity
(Decl
);
1999 if Nkind
(Nam
) = N_Selected_Component
then
2000 Pref
:= Prefix
(Nam
);
2001 Sel
:= Selector_Name
(Nam
);
2003 -- A discriminant renaming appears as
2004 -- Discr : constant ... := Prefix.Discr;
2006 if Ekind
(Obj
) = E_Constant
2007 and then Is_Entity_Name
(Sel
)
2008 and then Present
(Entity
(Sel
))
2009 and then Ekind
(Entity
(Sel
)) = E_Discriminant
2013 -- A protection field renaming appears as
2014 -- Prot : ... := _object._object;
2016 elsif Ekind
(Obj
) = E_Variable
2017 and then Nkind
(Pref
) = N_Identifier
2018 and then Chars
(Pref
) = Name_uObject
2019 and then Nkind
(Sel
) = N_Identifier
2020 and then Chars
(Sel
) = Name_uObject
2028 end Is_Prologue_Renaming
;
2030 -------------------------
2031 -- Merge_Preconditions --
2032 -------------------------
2034 procedure Merge_Preconditions
(From
: Node_Id
; Into
: Node_Id
) is
2035 function Expression_Arg
(Prag
: Node_Id
) return Node_Id
;
2036 -- Return the boolean expression argument of a precondition while
2037 -- updating its parentheses count for the subsequent merge.
2039 function Message_Arg
(Prag
: Node_Id
) return Node_Id
;
2040 -- Return the message argument of a precondition
2042 --------------------
2043 -- Expression_Arg --
2044 --------------------
2046 function Expression_Arg
(Prag
: Node_Id
) return Node_Id
is
2047 Args
: constant List_Id
:= Pragma_Argument_Associations
(Prag
);
2048 Arg
: constant Node_Id
:= Get_Pragma_Arg
(Next
(First
(Args
)));
2051 if Paren_Count
(Arg
) = 0 then
2052 Set_Paren_Count
(Arg
, 1);
2062 function Message_Arg
(Prag
: Node_Id
) return Node_Id
is
2063 Args
: constant List_Id
:= Pragma_Argument_Associations
(Prag
);
2065 return Get_Pragma_Arg
(Last
(Args
));
2070 From_Expr
: constant Node_Id
:= Expression_Arg
(From
);
2071 From_Msg
: constant Node_Id
:= Message_Arg
(From
);
2072 Into_Expr
: constant Node_Id
:= Expression_Arg
(Into
);
2073 Into_Msg
: constant Node_Id
:= Message_Arg
(Into
);
2074 Loc
: constant Source_Ptr
:= Sloc
(Into
);
2076 -- Start of processing for Merge_Preconditions
2079 -- Merge the two preconditions by "or else"-ing them
2083 Right_Opnd
=> Relocate_Node
(Into_Expr
),
2084 Left_Opnd
=> From_Expr
));
2086 -- Merge the two error messages to produce a single message of the
2089 -- failed precondition from ...
2090 -- also failed inherited precondition from ...
2092 if not Exception_Locations_Suppressed
then
2093 Start_String
(Strval
(Into_Msg
));
2094 Store_String_Char
(ASCII
.LF
);
2095 Store_String_Chars
(" also ");
2096 Store_String_Chars
(Strval
(From_Msg
));
2098 Set_Strval
(Into_Msg
, End_String
);
2100 end Merge_Preconditions
;
2102 ----------------------
2103 -- Prepend_To_Decls --
2104 ----------------------
2106 procedure Prepend_To_Decls
(Item
: Node_Id
) is
2107 Decls
: List_Id
:= Declarations
(Body_Decl
);
2110 -- Ensure that the body has a declarative list
2114 Set_Declarations
(Body_Decl
, Decls
);
2117 Prepend_To
(Decls
, Item
);
2118 end Prepend_To_Decls
;
2120 ------------------------------
2121 -- Prepend_To_Decls_Or_Save --
2122 ------------------------------
2124 procedure Prepend_To_Decls_Or_Save
(Prag
: Node_Id
) is
2125 Check_Prag
: Node_Id
;
2128 Check_Prag
:= Build_Pragma_Check_Equivalent
(Prag
);
2130 -- Save the sole class-wide precondition (if any) for the next
2131 -- step, where it will be merged with inherited preconditions.
2133 if Class_Present
(Prag
) then
2134 pragma Assert
(No
(Class_Pre
));
2135 Class_Pre
:= Check_Prag
;
2137 -- Accumulate the corresponding Check pragmas at the top of the
2138 -- declarations. Prepending the items ensures that they will be
2139 -- evaluated in their original order.
2142 if Present
(Insert_Node
) then
2143 Insert_After
(Insert_Node
, Check_Prag
);
2145 Prepend_To_Decls
(Check_Prag
);
2148 Analyze
(Check_Prag
);
2150 end Prepend_To_Decls_Or_Save
;
2152 -------------------------------------
2153 -- Process_Inherited_Preconditions --
2154 -------------------------------------
2156 procedure Process_Inherited_Preconditions
is
2157 Subps
: constant Subprogram_List
:=
2158 Inherited_Subprograms
(Spec_Id
);
2159 Check_Prag
: Node_Id
;
2162 Subp_Id
: Entity_Id
;
2165 -- Process the contracts of all inherited subprograms, looking for
2166 -- class-wide preconditions.
2168 for Index
in Subps
'Range loop
2169 Subp_Id
:= Subps
(Index
);
2170 Items
:= Contract
(Subp_Id
);
2172 if Present
(Items
) then
2173 Prag
:= Pre_Post_Conditions
(Items
);
2174 while Present
(Prag
) loop
2175 if Pragma_Name
(Prag
) = Name_Precondition
2176 and then Class_Present
(Prag
)
2179 Build_Pragma_Check_Equivalent
2182 Inher_Id
=> Subp_Id
);
2184 -- The spec of an inherited subprogram already yielded
2185 -- a class-wide precondition. Merge the existing
2186 -- precondition with the current one using "or else".
2188 if Present
(Class_Pre
) then
2189 Merge_Preconditions
(Check_Prag
, Class_Pre
);
2191 Class_Pre
:= Check_Prag
;
2195 Prag
:= Next_Pragma
(Prag
);
2200 -- Add the merged class-wide preconditions
2202 if Present
(Class_Pre
) then
2203 Prepend_To_Decls
(Class_Pre
);
2204 Analyze
(Class_Pre
);
2206 end Process_Inherited_Preconditions
;
2208 -------------------------------
2209 -- Process_Preconditions_For --
2210 -------------------------------
2212 procedure Process_Preconditions_For
(Subp_Id
: Entity_Id
) is
2213 Items
: constant Node_Id
:= Contract
(Subp_Id
);
2216 Subp_Decl
: Node_Id
;
2219 -- Process the contract
2221 if Present
(Items
) then
2222 Prag
:= Pre_Post_Conditions
(Items
);
2223 while Present
(Prag
) loop
2224 if Pragma_Name
(Prag
) = Name_Precondition
then
2225 Prepend_To_Decls_Or_Save
(Prag
);
2228 Prag
:= Next_Pragma
(Prag
);
2232 -- The subprogram declaration being processed is actually a body
2233 -- stub. The stub may carry a precondition pragma, in which case
2234 -- it must be taken into account. The pragma appears after the
2237 Subp_Decl
:= Unit_Declaration_Node
(Subp_Id
);
2239 if Nkind
(Subp_Decl
) = N_Subprogram_Body_Stub
then
2241 -- Inspect the declarations following the body stub
2243 Decl
:= Next
(Subp_Decl
);
2244 while Present
(Decl
) loop
2246 -- Note that non-matching pragmas are skipped
2248 if Nkind
(Decl
) = N_Pragma
then
2249 if Pragma_Name
(Decl
) = Name_Precondition
then
2250 Prepend_To_Decls_Or_Save
(Decl
);
2253 -- Skip internally generated code
2255 elsif not Comes_From_Source
(Decl
) then
2258 -- Preconditions are usually grouped together. There is no
2259 -- need to inspect the whole declarative list.
2268 end Process_Preconditions_For
;
2272 Decls
: constant List_Id
:= Declarations
(Body_Decl
);
2275 -- Start of processing for Process_Preconditions
2278 -- Find the proper insertion point for all pragma Check equivalents
2280 if Present
(Decls
) then
2281 Decl
:= First
(Decls
);
2282 while Present
(Decl
) loop
2284 -- First source declaration terminates the search, because all
2285 -- preconditions must be evaluated prior to it, by definition.
2287 if Comes_From_Source
(Decl
) then
2290 -- Certain internally generated object renamings such as those
2291 -- for discriminants and protection fields must be elaborated
2292 -- before the preconditions are evaluated, as their expressions
2293 -- may mention the discriminants.
2295 elsif Is_Prologue_Renaming
(Decl
) then
2296 Insert_Node
:= Decl
;
2298 -- Otherwise the declaration does not come from source. This
2299 -- also terminates the search, because internal code may raise
2300 -- exceptions which should not preempt the preconditions.
2310 -- The processing of preconditions is done in reverse order (body
2311 -- first), because each pragma Check equivalent is inserted at the
2312 -- top of the declarations. This ensures that the final order is
2313 -- consistent with following diagram:
2315 -- <inherited preconditions>
2316 -- <preconditions from spec>
2317 -- <preconditions from body>
2319 Process_Preconditions_For
(Body_Id
);
2321 if Present
(Spec_Id
) then
2322 Process_Preconditions_For
(Spec_Id
);
2323 Process_Inherited_Preconditions
;
2325 end Process_Preconditions
;
2329 Restore_Scope
: Boolean := False;
2331 Stmts
: List_Id
:= No_List
;
2332 Subp_Id
: Entity_Id
;
2334 -- Start of processing for Expand_Subprogram_Contract
2337 -- Obtain the entity of the initial declaration
2339 if Present
(Spec_Id
) then
2345 -- Do not perform expansion activity when it is not needed
2347 if not Expander_Active
then
2350 -- ASIS requires an unaltered tree
2352 elsif ASIS_Mode
then
2355 -- GNATprove does not need the executable semantics of a contract
2357 elsif GNATprove_Mode
then
2360 -- The contract of a generic subprogram or one declared in a generic
2361 -- context is not expanded, as the corresponding instance will provide
2362 -- the executable semantics of the contract.
2364 elsif Is_Generic_Subprogram
(Subp_Id
) or else Inside_A_Generic
then
2367 -- All subprograms carry a contract, but for some it is not significant
2368 -- and should not be processed. This is a small optimization.
2370 elsif not Has_Significant_Contract
(Subp_Id
) then
2373 -- The contract of an ignored Ghost subprogram does not need expansion,
2374 -- because the subprogram and all calls to it will be removed.
2376 elsif Is_Ignored_Ghost_Entity
(Subp_Id
) then
2380 -- Do not re-expand the same contract. This scenario occurs when a
2381 -- construct is rewritten into something else during its analysis
2382 -- (expression functions for instance).
2384 if Has_Expanded_Contract
(Subp_Id
) then
2387 -- Otherwise mark the subprogram
2390 Set_Has_Expanded_Contract
(Subp_Id
);
2393 -- Ensure that the formal parameters are visible when expanding all
2396 if not In_Open_Scopes
(Subp_Id
) then
2397 Restore_Scope
:= True;
2398 Push_Scope
(Subp_Id
);
2400 if Is_Generic_Subprogram
(Subp_Id
) then
2401 Install_Generic_Formals
(Subp_Id
);
2403 Install_Formals
(Subp_Id
);
2407 -- The expansion of a subprogram contract involves the creation of Check
2408 -- pragmas to verify the contract assertions of the spec and body in a
2409 -- particular order. The order is as follows:
2411 -- function Example (...) return ... is
2412 -- procedure _Postconditions (...) is
2414 -- <refined postconditions from body>
2415 -- <postconditions from body>
2416 -- <postconditions from spec>
2417 -- <inherited postconditions>
2418 -- <contract case consequences>
2419 -- <invariant check of function result>
2420 -- <invariant and predicate checks of parameters>
2421 -- end _Postconditions;
2423 -- <inherited preconditions>
2424 -- <preconditions from spec>
2425 -- <preconditions from body>
2426 -- <contract case conditions>
2428 -- <source declarations>
2430 -- <source statements>
2432 -- _Preconditions (Result);
2436 -- Routine _Postconditions holds all contract assertions that must be
2437 -- verified on exit from the related subprogram.
2439 -- Step 1: Handle all preconditions. This action must come before the
2440 -- processing of pragma Contract_Cases because the pragma prepends items
2441 -- to the body declarations.
2443 Process_Preconditions
;
2445 -- Step 2: Handle all postconditions. This action must come before the
2446 -- processing of pragma Contract_Cases because the pragma appends items
2449 Process_Postconditions
(Stmts
);
2451 -- Step 3: Handle pragma Contract_Cases. This action must come before
2452 -- the processing of invariants and predicates because those append
2453 -- items to list Stmts.
2455 Process_Contract_Cases
(Stmts
);
2457 -- Step 4: Apply invariant and predicate checks on a function result and
2458 -- all formals. The resulting checks are accumulated in list Stmts.
2460 Add_Invariant_And_Predicate_Checks
(Subp_Id
, Stmts
, Result
);
2462 -- Step 5: Construct procedure _Postconditions
2464 Build_Postconditions_Procedure
(Subp_Id
, Stmts
, Result
);
2466 if Restore_Scope
then
2469 end Expand_Subprogram_Contract
;
2471 ---------------------------------
2472 -- Inherit_Subprogram_Contract --
2473 ---------------------------------
2475 procedure Inherit_Subprogram_Contract
2477 From_Subp
: Entity_Id
)
2479 procedure Inherit_Pragma
(Prag_Id
: Pragma_Id
);
2480 -- Propagate a pragma denoted by Prag_Id from From_Subp's contract to
2483 --------------------
2484 -- Inherit_Pragma --
2485 --------------------
2487 procedure Inherit_Pragma
(Prag_Id
: Pragma_Id
) is
2488 Prag
: constant Node_Id
:= Get_Pragma
(From_Subp
, Prag_Id
);
2492 -- A pragma cannot be part of more than one First_Pragma/Next_Pragma
2493 -- chains, therefore the node must be replicated. The new pragma is
2494 -- flagged as inherited for distinction purposes.
2496 if Present
(Prag
) then
2497 New_Prag
:= New_Copy_Tree
(Prag
);
2498 Set_Is_Inherited_Pragma
(New_Prag
);
2500 Add_Contract_Item
(New_Prag
, Subp
);
2504 -- Start of processing for Inherit_Subprogram_Contract
2507 -- Inheritance is carried out only when both entities are subprograms
2510 if Is_Subprogram_Or_Generic_Subprogram
(Subp
)
2511 and then Is_Subprogram_Or_Generic_Subprogram
(From_Subp
)
2512 and then Present
(Contract
(From_Subp
))
2514 Inherit_Pragma
(Pragma_Extensions_Visible
);
2516 end Inherit_Subprogram_Contract
;
2518 -------------------------------------
2519 -- Instantiate_Subprogram_Contract --
2520 -------------------------------------
2522 procedure Instantiate_Subprogram_Contract
(Templ
: Node_Id
; L
: List_Id
) is
2523 procedure Instantiate_Pragmas
(First_Prag
: Node_Id
);
2524 -- Instantiate all contract-related source pragmas found in the list,
2525 -- starting with pragma First_Prag. Each instantiated pragma is added
2528 -------------------------
2529 -- Instantiate_Pragmas --
2530 -------------------------
2532 procedure Instantiate_Pragmas
(First_Prag
: Node_Id
) is
2533 Inst_Prag
: Node_Id
;
2538 while Present
(Prag
) loop
2539 if Is_Generic_Contract_Pragma
(Prag
) then
2541 Copy_Generic_Node
(Prag
, Empty
, Instantiating
=> True);
2543 Set_Analyzed
(Inst_Prag
, False);
2544 Append_To
(L
, Inst_Prag
);
2547 Prag
:= Next_Pragma
(Prag
);
2549 end Instantiate_Pragmas
;
2553 Items
: constant Node_Id
:= Contract
(Defining_Entity
(Templ
));
2555 -- Start of processing for Instantiate_Subprogram_Contract
2558 if Present
(Items
) then
2559 Instantiate_Pragmas
(Pre_Post_Conditions
(Items
));
2560 Instantiate_Pragmas
(Contract_Test_Cases
(Items
));
2561 Instantiate_Pragmas
(Classifications
(Items
));
2563 end Instantiate_Subprogram_Contract
;
2565 ----------------------------------------
2566 -- Save_Global_References_In_Contract --
2567 ----------------------------------------
2569 procedure Save_Global_References_In_Contract
2573 procedure Save_Global_References_In_List
(First_Prag
: Node_Id
);
2574 -- Save all global references in contract-related source pragmas found
2575 -- in the list, starting with pragma First_Prag.
2577 ------------------------------------
2578 -- Save_Global_References_In_List --
2579 ------------------------------------
2581 procedure Save_Global_References_In_List
(First_Prag
: Node_Id
) is
2586 while Present
(Prag
) loop
2587 if Is_Generic_Contract_Pragma
(Prag
) then
2588 Save_Global_References
(Prag
);
2591 Prag
:= Next_Pragma
(Prag
);
2593 end Save_Global_References_In_List
;
2597 Items
: constant Node_Id
:= Contract
(Defining_Entity
(Templ
));
2599 -- Start of processing for Save_Global_References_In_Contract
2602 -- The entity of the analyzed generic copy must be on the scope stack
2603 -- to ensure proper detection of global references.
2605 Push_Scope
(Gen_Id
);
2607 if Permits_Aspect_Specifications
(Templ
)
2608 and then Has_Aspects
(Templ
)
2610 Save_Global_References_In_Aspects
(Templ
);
2613 if Present
(Items
) then
2614 Save_Global_References_In_List
(Pre_Post_Conditions
(Items
));
2615 Save_Global_References_In_List
(Contract_Test_Cases
(Items
));
2616 Save_Global_References_In_List
(Classifications
(Items
));
2620 end Save_Global_References_In_Contract
;