1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- C O N T R A C T S --
9 -- Copyright (C) 2015-2018, 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 Debug
; use Debug
;
29 with Einfo
; use Einfo
;
30 with Elists
; use Elists
;
31 with Errout
; use Errout
;
32 with Exp_Prag
; use Exp_Prag
;
33 with Exp_Tss
; use Exp_Tss
;
34 with Exp_Util
; use Exp_Util
;
35 with Freeze
; use Freeze
;
36 with Namet
; use Namet
;
37 with Nlists
; use Nlists
;
38 with Nmake
; use Nmake
;
41 with Sem_Aux
; use Sem_Aux
;
42 with Sem_Ch6
; use Sem_Ch6
;
43 with Sem_Ch8
; use Sem_Ch8
;
44 with Sem_Ch12
; use Sem_Ch12
;
45 with Sem_Ch13
; use Sem_Ch13
;
46 with Sem_Disp
; use Sem_Disp
;
47 with Sem_Prag
; use Sem_Prag
;
48 with Sem_Util
; use Sem_Util
;
49 with Sinfo
; use Sinfo
;
50 with Snames
; use Snames
;
51 with Stand
; use Stand
;
52 with Stringt
; use Stringt
;
53 with SCIL_LL
; use SCIL_LL
;
54 with Tbuild
; use Tbuild
;
56 package body Contracts
is
58 procedure Analyze_Package_Instantiation_Contract
(Inst_Id
: Entity_Id
);
59 -- Analyze all delayed pragmas chained on the contract of package
60 -- instantiation Inst_Id as if they appear at the end of a declarative
61 -- region. The pragmas in question are:
65 procedure Build_And_Analyze_Contract_Only_Subprograms
(L
: List_Id
);
66 -- (CodePeer): Subsidiary procedure to Analyze_Contracts which builds the
67 -- contract-only subprogram body of eligible subprograms found in L, adds
68 -- them to their corresponding list of declarations, and analyzes them.
70 procedure Expand_Subprogram_Contract
(Body_Id
: Entity_Id
);
71 -- Expand the contracts of a subprogram body and its correspoding spec (if
72 -- any). This routine processes all [refined] pre- and postconditions as
73 -- well as Contract_Cases, invariants and predicates. Body_Id denotes the
74 -- entity of the subprogram body.
76 -----------------------
77 -- Add_Contract_Item --
78 -----------------------
80 procedure Add_Contract_Item
(Prag
: Node_Id
; Id
: Entity_Id
) is
81 Items
: Node_Id
:= Contract
(Id
);
83 procedure Add_Classification
;
84 -- Prepend Prag to the list of classifications
86 procedure Add_Contract_Test_Case
;
87 -- Prepend Prag to the list of contract and test cases
89 procedure Add_Pre_Post_Condition
;
90 -- Prepend Prag to the list of pre- and postconditions
92 ------------------------
93 -- Add_Classification --
94 ------------------------
96 procedure Add_Classification
is
98 Set_Next_Pragma
(Prag
, Classifications
(Items
));
99 Set_Classifications
(Items
, Prag
);
100 end Add_Classification
;
102 ----------------------------
103 -- Add_Contract_Test_Case --
104 ----------------------------
106 procedure Add_Contract_Test_Case
is
108 Set_Next_Pragma
(Prag
, Contract_Test_Cases
(Items
));
109 Set_Contract_Test_Cases
(Items
, Prag
);
110 end Add_Contract_Test_Case
;
112 ----------------------------
113 -- Add_Pre_Post_Condition --
114 ----------------------------
116 procedure Add_Pre_Post_Condition
is
118 Set_Next_Pragma
(Prag
, Pre_Post_Conditions
(Items
));
119 Set_Pre_Post_Conditions
(Items
, Prag
);
120 end Add_Pre_Post_Condition
;
124 -- A contract must contain only pragmas
126 pragma Assert
(Nkind
(Prag
) = N_Pragma
);
127 Prag_Nam
: constant Name_Id
:= Pragma_Name
(Prag
);
129 -- Start of processing for Add_Contract_Item
132 -- Create a new contract when adding the first item
135 Items
:= Make_Contract
(Sloc
(Id
));
136 Set_Contract
(Id
, Items
);
139 -- Constants, the applicable pragmas are:
142 if Ekind
(Id
) = E_Constant
then
143 if Prag_Nam
= Name_Part_Of
then
146 -- The pragma is not a proper contract item
152 -- Entry bodies, the applicable pragmas are:
157 elsif Is_Entry_Body
(Id
) then
158 if Nam_In
(Prag_Nam
, Name_Refined_Depends
, Name_Refined_Global
) then
161 elsif Prag_Nam
= Name_Refined_Post
then
162 Add_Pre_Post_Condition
;
164 -- The pragma is not a proper contract item
170 -- Entry or subprogram declarations, the applicable pragmas are:
174 -- Extensions_Visible
182 elsif Is_Entry_Declaration
(Id
)
183 or else Ekind_In
(Id
, E_Function
,
188 if Nam_In
(Prag_Nam
, Name_Attach_Handler
, Name_Interrupt_Handler
)
189 and then Ekind_In
(Id
, E_Generic_Procedure
, E_Procedure
)
193 elsif Nam_In
(Prag_Nam
, Name_Depends
,
194 Name_Extensions_Visible
,
199 elsif Prag_Nam
= Name_Volatile_Function
200 and then Ekind_In
(Id
, E_Function
, E_Generic_Function
)
204 elsif Nam_In
(Prag_Nam
, Name_Contract_Cases
, Name_Test_Case
) then
205 Add_Contract_Test_Case
;
207 elsif Nam_In
(Prag_Nam
, Name_Postcondition
, Name_Precondition
) then
208 Add_Pre_Post_Condition
;
210 -- The pragma is not a proper contract item
216 -- Packages or instantiations, the applicable pragmas are:
220 -- Part_Of (instantiation only)
222 elsif Ekind_In
(Id
, E_Generic_Package
, E_Package
) then
223 if Nam_In
(Prag_Nam
, Name_Abstract_State
,
224 Name_Initial_Condition
,
229 -- Indicator Part_Of must be associated with a package instantiation
231 elsif Prag_Nam
= Name_Part_Of
and then Is_Generic_Instance
(Id
) then
234 -- The pragma is not a proper contract item
240 -- Package bodies, the applicable pragmas are:
243 elsif Ekind
(Id
) = E_Package_Body
then
244 if Prag_Nam
= Name_Refined_State
then
247 -- The pragma is not a proper contract item
253 -- Protected units, the applicable pragmas are:
256 elsif Ekind
(Id
) = E_Protected_Type
then
257 if Prag_Nam
= Name_Part_Of
then
260 -- The pragma is not a proper contract item
266 -- Subprogram bodies, the applicable pragmas are:
273 elsif Ekind
(Id
) = E_Subprogram_Body
then
274 if Nam_In
(Prag_Nam
, Name_Refined_Depends
, Name_Refined_Global
) then
277 elsif Nam_In
(Prag_Nam
, Name_Postcondition
,
281 Add_Pre_Post_Condition
;
283 -- The pragma is not a proper contract item
289 -- Task bodies, the applicable pragmas are:
293 elsif Ekind
(Id
) = E_Task_Body
then
294 if Nam_In
(Prag_Nam
, Name_Refined_Depends
, Name_Refined_Global
) then
297 -- The pragma is not a proper contract item
303 -- Task units, the applicable pragmas are:
308 elsif Ekind
(Id
) = E_Task_Type
then
309 if Nam_In
(Prag_Nam
, Name_Depends
, Name_Global
, Name_Part_Of
) then
312 -- The pragma is not a proper contract item
318 -- Variables, the applicable pragmas are:
321 -- Constant_After_Elaboration
328 elsif Ekind
(Id
) = E_Variable
then
329 if Nam_In
(Prag_Nam
, Name_Async_Readers
,
331 Name_Constant_After_Elaboration
,
333 Name_Effective_Reads
,
334 Name_Effective_Writes
,
340 -- The pragma is not a proper contract item
346 end Add_Contract_Item
;
348 -----------------------
349 -- Analyze_Contracts --
350 -----------------------
352 procedure Analyze_Contracts
(L
: List_Id
) is
356 if CodePeer_Mode
and then Debug_Flag_Dot_KK
then
357 Build_And_Analyze_Contract_Only_Subprograms
(L
);
361 while Present
(Decl
) loop
363 -- Entry or subprogram declarations
365 if Nkind_In
(Decl
, N_Abstract_Subprogram_Declaration
,
367 N_Generic_Subprogram_Declaration
,
368 N_Subprogram_Declaration
)
371 Subp_Id
: constant Entity_Id
:= Defining_Entity
(Decl
);
374 Analyze_Entry_Or_Subprogram_Contract
(Subp_Id
);
376 -- If analysis of a class-wide pre/postcondition indicates
377 -- that a class-wide clone is needed, analyze its declaration
378 -- now. Its body is created when the body of the original
379 -- operation is analyzed (and rewritten).
381 if Is_Subprogram
(Subp_Id
)
382 and then Present
(Class_Wide_Clone
(Subp_Id
))
384 Analyze
(Unit_Declaration_Node
(Class_Wide_Clone
(Subp_Id
)));
388 -- Entry or subprogram bodies
390 elsif Nkind_In
(Decl
, N_Entry_Body
, N_Subprogram_Body
) then
391 Analyze_Entry_Or_Subprogram_Body_Contract
(Defining_Entity
(Decl
));
395 elsif Nkind
(Decl
) = N_Object_Declaration
then
396 Analyze_Object_Contract
(Defining_Entity
(Decl
));
398 -- Package instantiation
400 elsif Nkind
(Decl
) = N_Package_Instantiation
then
401 Analyze_Package_Instantiation_Contract
(Defining_Entity
(Decl
));
405 elsif Nkind_In
(Decl
, N_Protected_Type_Declaration
,
406 N_Single_Protected_Declaration
)
408 Analyze_Protected_Contract
(Defining_Entity
(Decl
));
410 -- Subprogram body stubs
412 elsif Nkind
(Decl
) = N_Subprogram_Body_Stub
then
413 Analyze_Subprogram_Body_Stub_Contract
(Defining_Entity
(Decl
));
417 elsif Nkind_In
(Decl
, N_Single_Task_Declaration
,
418 N_Task_Type_Declaration
)
420 Analyze_Task_Contract
(Defining_Entity
(Decl
));
422 -- For type declarations, we need to do the preanalysis of Iterable
423 -- aspect specifications.
425 -- Other type aspects need to be resolved here???
427 elsif Nkind
(Decl
) = N_Private_Type_Declaration
428 and then Present
(Aspect_Specifications
(Decl
))
431 E
: constant Entity_Id
:= Defining_Identifier
(Decl
);
432 It
: constant Node_Id
:= Find_Aspect
(E
, Aspect_Iterable
);
436 Validate_Iterable_Aspect
(E
, It
);
443 end Analyze_Contracts
;
445 -----------------------------------------------
446 -- Analyze_Entry_Or_Subprogram_Body_Contract --
447 -----------------------------------------------
449 -- WARNING: This routine manages SPARK regions. Return statements must be
450 -- replaced by gotos which jump to the end of the routine and restore the
453 procedure Analyze_Entry_Or_Subprogram_Body_Contract
(Body_Id
: Entity_Id
) is
454 Body_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Body_Id
);
455 Items
: constant Node_Id
:= Contract
(Body_Id
);
456 Spec_Id
: constant Entity_Id
:= Unique_Defining_Entity
(Body_Decl
);
458 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
459 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
460 -- Save the SPARK_Mode-related data to restore on exit
463 -- When a subprogram body declaration is illegal, its defining entity is
464 -- left unanalyzed. There is nothing left to do in this case because the
465 -- body lacks a contract, or even a proper Ekind.
467 if Ekind
(Body_Id
) = E_Void
then
470 -- Do not analyze a contract multiple times
472 elsif Present
(Items
) then
473 if Analyzed
(Items
) then
476 Set_Analyzed
(Items
);
480 -- Due to the timing of contract analysis, delayed pragmas may be
481 -- subject to the wrong SPARK_Mode, usually that of the enclosing
482 -- context. To remedy this, restore the original SPARK_Mode of the
483 -- related subprogram body.
485 Set_SPARK_Mode
(Body_Id
);
487 -- Ensure that the contract cases or postconditions mention 'Result or
488 -- define a post-state.
490 Check_Result_And_Post_State
(Body_Id
);
492 -- A stand-alone nonvolatile function body cannot have an effectively
493 -- volatile formal parameter or return type (SPARK RM 7.1.3(9)). This
494 -- check is relevant only when SPARK_Mode is on, as it is not a standard
495 -- legality rule. The check is performed here because Volatile_Function
496 -- is processed after the analysis of the related subprogram body. The
497 -- check only applies to source subprograms and not to generated TSS
501 and then Ekind_In
(Body_Id
, E_Function
, E_Generic_Function
)
502 and then Comes_From_Source
(Spec_Id
)
503 and then not Is_Volatile_Function
(Body_Id
)
505 Check_Nonvolatile_Function_Profile
(Body_Id
);
508 -- Restore the SPARK_Mode of the enclosing context after all delayed
509 -- pragmas have been analyzed.
511 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
513 -- Capture all global references in a generic subprogram body now that
514 -- the contract has been analyzed.
516 if Is_Generic_Declaration_Or_Body
(Body_Decl
) then
517 Save_Global_References_In_Contract
518 (Templ
=> Original_Node
(Body_Decl
),
522 -- Deal with preconditions, [refined] postconditions, Contract_Cases,
523 -- invariants and predicates associated with body and its spec. Do not
524 -- expand the contract of subprogram body stubs.
526 if Nkind
(Body_Decl
) = N_Subprogram_Body
then
527 Expand_Subprogram_Contract
(Body_Id
);
529 end Analyze_Entry_Or_Subprogram_Body_Contract
;
531 ------------------------------------------
532 -- Analyze_Entry_Or_Subprogram_Contract --
533 ------------------------------------------
535 -- WARNING: This routine manages SPARK regions. Return statements must be
536 -- replaced by gotos which jump to the end of the routine and restore the
539 procedure Analyze_Entry_Or_Subprogram_Contract
540 (Subp_Id
: Entity_Id
;
541 Freeze_Id
: Entity_Id
:= Empty
)
543 Items
: constant Node_Id
:= Contract
(Subp_Id
);
544 Subp_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Subp_Id
);
546 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
547 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
548 -- Save the SPARK_Mode-related data to restore on exit
550 Skip_Assert_Exprs
: constant Boolean :=
551 Ekind_In
(Subp_Id
, E_Entry
, E_Entry_Family
)
552 and then not ASIS_Mode
553 and then not GNATprove_Mode
;
555 Depends
: Node_Id
:= Empty
;
556 Global
: Node_Id
:= Empty
;
561 -- Do not analyze a contract multiple times
563 if Present
(Items
) then
564 if Analyzed
(Items
) then
567 Set_Analyzed
(Items
);
571 -- Due to the timing of contract analysis, delayed pragmas may be
572 -- subject to the wrong SPARK_Mode, usually that of the enclosing
573 -- context. To remedy this, restore the original SPARK_Mode of the
574 -- related subprogram body.
576 Set_SPARK_Mode
(Subp_Id
);
578 -- All subprograms carry a contract, but for some it is not significant
579 -- and should not be processed.
581 if not Has_Significant_Contract
(Subp_Id
) then
584 elsif Present
(Items
) then
586 -- Do not analyze the pre/postconditions of an entry declaration
587 -- unless annotating the original tree for ASIS or GNATprove. The
588 -- real analysis occurs when the pre/postconditons are relocated to
589 -- the contract wrapper procedure (see Build_Contract_Wrapper).
591 if Skip_Assert_Exprs
then
594 -- Otherwise analyze the pre/postconditions. Their expressions
595 -- might include references to types that are not frozen yet, in the
596 -- case where the body is a rewritten expression function that is a
597 -- completion, so freeze all types within before constructing the
603 Freeze_Types
: Boolean := False;
606 if Present
(Freeze_Id
) then
607 Bod
:= Unit_Declaration_Node
(Freeze_Id
);
609 if Nkind
(Bod
) = N_Subprogram_Body
610 and then Was_Expression_Function
(Bod
)
611 and then Ekind
(Subp_Id
) = E_Function
612 and then Chars
(Subp_Id
) = Chars
(Freeze_Id
)
613 and then Subp_Id
/= Freeze_Id
615 Freeze_Types
:= True;
619 Prag
:= Pre_Post_Conditions
(Items
);
620 while Present
(Prag
) loop
624 Typ
=> Standard_Boolean
,
625 Expr
=> Expression
(Corresponding_Aspect
(Prag
)),
629 Analyze_Pre_Post_Condition_In_Decl_Part
(Prag
, Freeze_Id
);
630 Prag
:= Next_Pragma
(Prag
);
635 -- Analyze contract-cases and test-cases
637 Prag
:= Contract_Test_Cases
(Items
);
638 while Present
(Prag
) loop
639 Prag_Nam
:= Pragma_Name
(Prag
);
641 if Prag_Nam
= Name_Contract_Cases
then
643 -- Do not analyze the contract cases of an entry declaration
644 -- unless annotating the original tree for ASIS or GNATprove.
645 -- The real analysis occurs when the contract cases are moved
646 -- to the contract wrapper procedure (Build_Contract_Wrapper).
648 if Skip_Assert_Exprs
then
651 -- Otherwise analyze the contract cases
654 Analyze_Contract_Cases_In_Decl_Part
(Prag
, Freeze_Id
);
657 pragma Assert
(Prag_Nam
= Name_Test_Case
);
658 Analyze_Test_Case_In_Decl_Part
(Prag
);
661 Prag
:= Next_Pragma
(Prag
);
664 -- Analyze classification pragmas
666 Prag
:= Classifications
(Items
);
667 while Present
(Prag
) loop
668 Prag_Nam
:= Pragma_Name
(Prag
);
670 if Prag_Nam
= Name_Depends
then
673 elsif Prag_Nam
= Name_Global
then
677 Prag
:= Next_Pragma
(Prag
);
680 -- Analyze Global first, as Depends may mention items classified in
681 -- the global categorization.
683 if Present
(Global
) then
684 Analyze_Global_In_Decl_Part
(Global
);
687 -- Depends must be analyzed after Global in order to see the modes of
690 if Present
(Depends
) then
691 Analyze_Depends_In_Decl_Part
(Depends
);
694 -- Ensure that the contract cases or postconditions mention 'Result
695 -- or define a post-state.
697 Check_Result_And_Post_State
(Subp_Id
);
700 -- A nonvolatile function cannot have an effectively volatile formal
701 -- parameter or return type (SPARK RM 7.1.3(9)). This check is relevant
702 -- only when SPARK_Mode is on, as it is not a standard legality rule.
703 -- The check is performed here because pragma Volatile_Function is
704 -- processed after the analysis of the related subprogram declaration.
707 and then Ekind_In
(Subp_Id
, E_Function
, E_Generic_Function
)
708 and then Comes_From_Source
(Subp_Id
)
709 and then not Is_Volatile_Function
(Subp_Id
)
711 Check_Nonvolatile_Function_Profile
(Subp_Id
);
714 -- Restore the SPARK_Mode of the enclosing context after all delayed
715 -- pragmas have been analyzed.
717 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
719 -- Capture all global references in a generic subprogram now that the
720 -- contract has been analyzed.
722 if Is_Generic_Declaration_Or_Body
(Subp_Decl
) then
723 Save_Global_References_In_Contract
724 (Templ
=> Original_Node
(Subp_Decl
),
727 end Analyze_Entry_Or_Subprogram_Contract
;
729 -----------------------------
730 -- Analyze_Object_Contract --
731 -----------------------------
733 -- WARNING: This routine manages SPARK regions. Return statements must be
734 -- replaced by gotos which jump to the end of the routine and restore the
737 procedure Analyze_Object_Contract
739 Freeze_Id
: Entity_Id
:= Empty
)
741 Obj_Typ
: constant Entity_Id
:= Etype
(Obj_Id
);
743 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
744 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
745 -- Save the SPARK_Mode-related data to restore on exit
747 AR_Val
: Boolean := False;
748 AW_Val
: Boolean := False;
749 ER_Val
: Boolean := False;
750 EW_Val
: Boolean := False;
754 Seen
: Boolean := False;
757 -- The loop parameter in an element iterator over a formal container
758 -- is declared with an object declaration, but no contracts apply.
760 if Ekind
(Obj_Id
) = E_Loop_Parameter
then
764 -- Do not analyze a contract multiple times
766 Items
:= Contract
(Obj_Id
);
768 if Present
(Items
) then
769 if Analyzed
(Items
) then
772 Set_Analyzed
(Items
);
776 -- The anonymous object created for a single concurrent type inherits
777 -- the SPARK_Mode from the type. Due to the timing of contract analysis,
778 -- delayed pragmas may be subject to the wrong SPARK_Mode, usually that
779 -- of the enclosing context. To remedy this, restore the original mode
780 -- of the related anonymous object.
782 if Is_Single_Concurrent_Object
(Obj_Id
)
783 and then Present
(SPARK_Pragma
(Obj_Id
))
785 Set_SPARK_Mode
(Obj_Id
);
788 -- Constant-related checks
790 if Ekind
(Obj_Id
) = E_Constant
then
792 -- Analyze indicator Part_Of
794 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Part_Of
);
796 -- Check whether the lack of indicator Part_Of agrees with the
797 -- placement of the constant with respect to the state space.
800 Check_Missing_Part_Of
(Obj_Id
);
803 -- A constant cannot be effectively volatile (SPARK RM 7.1.3(4)).
804 -- This check is relevant only when SPARK_Mode is on, as it is not
805 -- a standard Ada legality rule. Internally-generated constants that
806 -- map generic formals to actuals in instantiations are allowed to
810 and then Comes_From_Source
(Obj_Id
)
811 and then Is_Effectively_Volatile
(Obj_Id
)
812 and then No
(Corresponding_Generic_Association
(Parent
(Obj_Id
)))
814 Error_Msg_N
("constant cannot be volatile", Obj_Id
);
817 -- Variable-related checks
819 else pragma Assert
(Ekind
(Obj_Id
) = E_Variable
);
821 -- Analyze all external properties
823 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Async_Readers
);
825 if Present
(Prag
) then
826 Analyze_External_Property_In_Decl_Part
(Prag
, AR_Val
);
830 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Async_Writers
);
832 if Present
(Prag
) then
833 Analyze_External_Property_In_Decl_Part
(Prag
, AW_Val
);
837 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Effective_Reads
);
839 if Present
(Prag
) then
840 Analyze_External_Property_In_Decl_Part
(Prag
, ER_Val
);
844 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Effective_Writes
);
846 if Present
(Prag
) then
847 Analyze_External_Property_In_Decl_Part
(Prag
, EW_Val
);
851 -- Verify the mutual interaction of the various external properties
854 Check_External_Properties
(Obj_Id
, AR_Val
, AW_Val
, ER_Val
, EW_Val
);
857 -- The anonymous object created for a single concurrent type carries
858 -- pragmas Depends and Globat of the type.
860 if Is_Single_Concurrent_Object
(Obj_Id
) then
862 -- Analyze Global first, as Depends may mention items classified
863 -- in the global categorization.
865 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Global
);
867 if Present
(Prag
) then
868 Analyze_Global_In_Decl_Part
(Prag
);
871 -- Depends must be analyzed after Global in order to see the modes
872 -- of all global items.
874 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Depends
);
876 if Present
(Prag
) then
877 Analyze_Depends_In_Decl_Part
(Prag
);
881 Prag
:= Get_Pragma
(Obj_Id
, Pragma_Part_Of
);
883 -- Analyze indicator Part_Of
885 if Present
(Prag
) then
886 Analyze_Part_Of_In_Decl_Part
(Prag
, Freeze_Id
);
888 -- The variable is a constituent of a single protected/task type
889 -- and behaves as a component of the type. Verify that references
890 -- to the variable occur within the definition or body of the type
893 if Present
(Encapsulating_State
(Obj_Id
))
894 and then Is_Single_Concurrent_Object
895 (Encapsulating_State
(Obj_Id
))
896 and then Present
(Part_Of_References
(Obj_Id
))
898 Ref_Elmt
:= First_Elmt
(Part_Of_References
(Obj_Id
));
899 while Present
(Ref_Elmt
) loop
900 Check_Part_Of_Reference
(Obj_Id
, Node
(Ref_Elmt
));
901 Next_Elmt
(Ref_Elmt
);
905 -- Otherwise check whether the lack of indicator Part_Of agrees with
906 -- the placement of the variable with respect to the state space.
909 Check_Missing_Part_Of
(Obj_Id
);
912 -- The following checks are relevant only when SPARK_Mode is on, as
913 -- they are not standard Ada legality rules. Internally generated
914 -- temporaries are ignored.
916 if SPARK_Mode
= On
and then Comes_From_Source
(Obj_Id
) then
917 if Is_Effectively_Volatile
(Obj_Id
) then
919 -- The declaration of an effectively volatile object must
920 -- appear at the library level (SPARK RM 7.1.3(3), C.6(6)).
922 if not Is_Library_Level_Entity
(Obj_Id
) then
924 ("volatile variable & must be declared at library level "
925 & "(SPARK RM 7.1.3(3))", Obj_Id
);
927 -- An object of a discriminated type cannot be effectively
928 -- volatile except for protected objects (SPARK RM 7.1.3(5)).
930 elsif Has_Discriminants
(Obj_Typ
)
931 and then not Is_Protected_Type
(Obj_Typ
)
934 ("discriminated object & cannot be volatile", Obj_Id
);
937 -- The object is not effectively volatile
940 -- A non-effectively volatile object cannot have effectively
941 -- volatile components (SPARK RM 7.1.3(6)).
943 if not Is_Effectively_Volatile
(Obj_Id
)
944 and then Has_Volatile_Component
(Obj_Typ
)
947 ("non-volatile object & cannot have volatile components",
956 if Comes_From_Source
(Obj_Id
) and then Is_Ghost_Entity
(Obj_Id
) then
958 -- A Ghost object cannot be of a type that yields a synchronized
959 -- object (SPARK RM 6.9(19)).
961 if Yields_Synchronized_Object
(Obj_Typ
) then
962 Error_Msg_N
("ghost object & cannot be synchronized", Obj_Id
);
964 -- A Ghost object cannot be effectively volatile (SPARK RM 6.9(7) and
965 -- SPARK RM 6.9(19)).
967 elsif Is_Effectively_Volatile
(Obj_Id
) then
968 Error_Msg_N
("ghost object & cannot be volatile", Obj_Id
);
970 -- A Ghost object cannot be imported or exported (SPARK RM 6.9(7)).
971 -- One exception to this is the object that represents the dispatch
972 -- table of a Ghost tagged type, as the symbol needs to be exported.
974 elsif Is_Exported
(Obj_Id
) then
975 Error_Msg_N
("ghost object & cannot be exported", Obj_Id
);
977 elsif Is_Imported
(Obj_Id
) then
978 Error_Msg_N
("ghost object & cannot be imported", Obj_Id
);
982 -- Restore the SPARK_Mode of the enclosing context after all delayed
983 -- pragmas have been analyzed.
985 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
986 end Analyze_Object_Contract
;
988 -----------------------------------
989 -- Analyze_Package_Body_Contract --
990 -----------------------------------
992 -- WARNING: This routine manages SPARK regions. Return statements must be
993 -- replaced by gotos which jump to the end of the routine and restore the
996 procedure Analyze_Package_Body_Contract
997 (Body_Id
: Entity_Id
;
998 Freeze_Id
: Entity_Id
:= Empty
)
1000 Body_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Body_Id
);
1001 Items
: constant Node_Id
:= Contract
(Body_Id
);
1002 Spec_Id
: constant Entity_Id
:= Spec_Entity
(Body_Id
);
1004 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
1005 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
1006 -- Save the SPARK_Mode-related data to restore on exit
1008 Ref_State
: Node_Id
;
1011 -- Do not analyze a contract multiple times
1013 if Present
(Items
) then
1014 if Analyzed
(Items
) then
1017 Set_Analyzed
(Items
);
1021 -- Due to the timing of contract analysis, delayed pragmas may be
1022 -- subject to the wrong SPARK_Mode, usually that of the enclosing
1023 -- context. To remedy this, restore the original SPARK_Mode of the
1024 -- related package body.
1026 Set_SPARK_Mode
(Body_Id
);
1028 Ref_State
:= Get_Pragma
(Body_Id
, Pragma_Refined_State
);
1030 -- The analysis of pragma Refined_State detects whether the spec has
1031 -- abstract states available for refinement.
1033 if Present
(Ref_State
) then
1034 Analyze_Refined_State_In_Decl_Part
(Ref_State
, Freeze_Id
);
1037 -- Restore the SPARK_Mode of the enclosing context after all delayed
1038 -- pragmas have been analyzed.
1040 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
1042 -- Capture all global references in a generic package body now that the
1043 -- contract has been analyzed.
1045 if Is_Generic_Declaration_Or_Body
(Body_Decl
) then
1046 Save_Global_References_In_Contract
1047 (Templ
=> Original_Node
(Body_Decl
),
1050 end Analyze_Package_Body_Contract
;
1052 ------------------------------
1053 -- Analyze_Package_Contract --
1054 ------------------------------
1056 -- WARNING: This routine manages SPARK regions. Return statements must be
1057 -- replaced by gotos which jump to the end of the routine and restore the
1060 procedure Analyze_Package_Contract
(Pack_Id
: Entity_Id
) is
1061 Items
: constant Node_Id
:= Contract
(Pack_Id
);
1062 Pack_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Pack_Id
);
1064 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
1065 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
1066 -- Save the SPARK_Mode-related data to restore on exit
1068 Init
: Node_Id
:= Empty
;
1069 Init_Cond
: Node_Id
:= Empty
;
1074 -- Do not analyze a contract multiple times
1076 if Present
(Items
) then
1077 if Analyzed
(Items
) then
1080 Set_Analyzed
(Items
);
1084 -- Due to the timing of contract analysis, delayed pragmas may be
1085 -- subject to the wrong SPARK_Mode, usually that of the enclosing
1086 -- context. To remedy this, restore the original SPARK_Mode of the
1089 Set_SPARK_Mode
(Pack_Id
);
1091 if Present
(Items
) then
1093 -- Locate and store pragmas Initial_Condition and Initializes, since
1094 -- their order of analysis matters.
1096 Prag
:= Classifications
(Items
);
1097 while Present
(Prag
) loop
1098 Prag_Nam
:= Pragma_Name
(Prag
);
1100 if Prag_Nam
= Name_Initial_Condition
then
1103 elsif Prag_Nam
= Name_Initializes
then
1107 Prag
:= Next_Pragma
(Prag
);
1110 -- Analyze the initialization-related pragmas. Initializes must come
1111 -- before Initial_Condition due to item dependencies.
1113 if Present
(Init
) then
1114 Analyze_Initializes_In_Decl_Part
(Init
);
1117 if Present
(Init_Cond
) then
1118 Analyze_Initial_Condition_In_Decl_Part
(Init_Cond
);
1122 -- Restore the SPARK_Mode of the enclosing context after all delayed
1123 -- pragmas have been analyzed.
1125 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
1127 -- Capture all global references in a generic package now that the
1128 -- contract has been analyzed.
1130 if Is_Generic_Declaration_Or_Body
(Pack_Decl
) then
1131 Save_Global_References_In_Contract
1132 (Templ
=> Original_Node
(Pack_Decl
),
1135 end Analyze_Package_Contract
;
1137 --------------------------------------------
1138 -- Analyze_Package_Instantiation_Contract --
1139 --------------------------------------------
1141 -- WARNING: This routine manages SPARK regions. Return statements must be
1142 -- replaced by gotos which jump to the end of the routine and restore the
1145 procedure Analyze_Package_Instantiation_Contract
(Inst_Id
: Entity_Id
) is
1146 Inst_Spec
: constant Node_Id
:=
1147 Instance_Spec
(Unit_Declaration_Node
(Inst_Id
));
1149 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
1150 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
1151 -- Save the SPARK_Mode-related data to restore on exit
1153 Pack_Id
: Entity_Id
;
1157 -- Nothing to do when the package instantiation is erroneous or left
1158 -- partially decorated.
1160 if No
(Inst_Spec
) then
1164 Pack_Id
:= Defining_Entity
(Inst_Spec
);
1165 Prag
:= Get_Pragma
(Pack_Id
, Pragma_Part_Of
);
1167 -- Due to the timing of contract analysis, delayed pragmas may be
1168 -- subject to the wrong SPARK_Mode, usually that of the enclosing
1169 -- context. To remedy this, restore the original SPARK_Mode of the
1172 Set_SPARK_Mode
(Pack_Id
);
1174 -- Check whether the lack of indicator Part_Of agrees with the placement
1175 -- of the package instantiation with respect to the state space. Nested
1176 -- package instantiations do not need to be checked because they inherit
1177 -- Part_Of indicator of the outermost package instantiation (see routine
1178 -- Propagate_Part_Of in Sem_Prag).
1183 elsif No
(Prag
) then
1184 Check_Missing_Part_Of
(Pack_Id
);
1187 -- Restore the SPARK_Mode of the enclosing context after all delayed
1188 -- pragmas have been analyzed.
1190 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
1191 end Analyze_Package_Instantiation_Contract
;
1193 --------------------------------
1194 -- Analyze_Protected_Contract --
1195 --------------------------------
1197 procedure Analyze_Protected_Contract
(Prot_Id
: Entity_Id
) is
1198 Items
: constant Node_Id
:= Contract
(Prot_Id
);
1201 -- Do not analyze a contract multiple times
1203 if Present
(Items
) then
1204 if Analyzed
(Items
) then
1207 Set_Analyzed
(Items
);
1210 end Analyze_Protected_Contract
;
1212 -------------------------------------------
1213 -- Analyze_Subprogram_Body_Stub_Contract --
1214 -------------------------------------------
1216 procedure Analyze_Subprogram_Body_Stub_Contract
(Stub_Id
: Entity_Id
) is
1217 Stub_Decl
: constant Node_Id
:= Parent
(Parent
(Stub_Id
));
1218 Spec_Id
: constant Entity_Id
:= Corresponding_Spec_Of_Stub
(Stub_Decl
);
1221 -- A subprogram body stub may act as its own spec or as the completion
1222 -- of a previous declaration. Depending on the context, the contract of
1223 -- the stub may contain two sets of pragmas.
1225 -- The stub is a completion, the applicable pragmas are:
1229 if Present
(Spec_Id
) then
1230 Analyze_Entry_Or_Subprogram_Body_Contract
(Stub_Id
);
1232 -- The stub acts as its own spec, the applicable pragmas are:
1241 Analyze_Entry_Or_Subprogram_Contract
(Stub_Id
);
1243 end Analyze_Subprogram_Body_Stub_Contract
;
1245 ---------------------------
1246 -- Analyze_Task_Contract --
1247 ---------------------------
1249 -- WARNING: This routine manages SPARK regions. Return statements must be
1250 -- replaced by gotos which jump to the end of the routine and restore the
1253 procedure Analyze_Task_Contract
(Task_Id
: Entity_Id
) is
1254 Items
: constant Node_Id
:= Contract
(Task_Id
);
1256 Saved_SM
: constant SPARK_Mode_Type
:= SPARK_Mode
;
1257 Saved_SMP
: constant Node_Id
:= SPARK_Mode_Pragma
;
1258 -- Save the SPARK_Mode-related data to restore on exit
1263 -- Do not analyze a contract multiple times
1265 if Present
(Items
) then
1266 if Analyzed
(Items
) then
1269 Set_Analyzed
(Items
);
1273 -- Due to the timing of contract analysis, delayed pragmas may be
1274 -- subject to the wrong SPARK_Mode, usually that of the enclosing
1275 -- context. To remedy this, restore the original SPARK_Mode of the
1276 -- related task unit.
1278 Set_SPARK_Mode
(Task_Id
);
1280 -- Analyze Global first, as Depends may mention items classified in the
1281 -- global categorization.
1283 Prag
:= Get_Pragma
(Task_Id
, Pragma_Global
);
1285 if Present
(Prag
) then
1286 Analyze_Global_In_Decl_Part
(Prag
);
1289 -- Depends must be analyzed after Global in order to see the modes of
1290 -- all global items.
1292 Prag
:= Get_Pragma
(Task_Id
, Pragma_Depends
);
1294 if Present
(Prag
) then
1295 Analyze_Depends_In_Decl_Part
(Prag
);
1298 -- Restore the SPARK_Mode of the enclosing context after all delayed
1299 -- pragmas have been analyzed.
1301 Restore_SPARK_Mode
(Saved_SM
, Saved_SMP
);
1302 end Analyze_Task_Contract
;
1304 -------------------------------------------------
1305 -- Build_And_Analyze_Contract_Only_Subprograms --
1306 -------------------------------------------------
1308 procedure Build_And_Analyze_Contract_Only_Subprograms
(L
: List_Id
) is
1309 procedure Analyze_Contract_Only_Subprograms
;
1310 -- Analyze the contract-only subprograms of L
1312 procedure Append_Contract_Only_Subprograms
(Subp_List
: List_Id
);
1313 -- Append the contract-only bodies of Subp_List to its declarations list
1315 function Build_Contract_Only_Subprogram
(E
: Entity_Id
) return Node_Id
;
1316 -- If E is an entity for a non-imported subprogram specification with
1317 -- pre/postconditions and we are compiling with CodePeer mode, then
1318 -- this procedure will create a wrapper to help Gnat2scil process its
1319 -- contracts. Return Empty if the wrapper cannot be built.
1321 function Build_Contract_Only_Subprograms
(L
: List_Id
) return List_Id
;
1322 -- Build the contract-only subprograms of all eligible subprograms found
1325 function Has_Private_Declarations
(N
: Node_Id
) return Boolean;
1326 -- Return True for package specs, task definitions, and protected type
1327 -- definitions whose list of private declarations is not empty.
1329 ---------------------------------------
1330 -- Analyze_Contract_Only_Subprograms --
1331 ---------------------------------------
1333 procedure Analyze_Contract_Only_Subprograms
is
1334 procedure Analyze_Contract_Only_Bodies
;
1335 -- Analyze all the contract-only bodies of L
1337 ----------------------------------
1338 -- Analyze_Contract_Only_Bodies --
1339 ----------------------------------
1341 procedure Analyze_Contract_Only_Bodies
is
1346 while Present
(Decl
) loop
1347 if Nkind
(Decl
) = N_Subprogram_Body
1348 and then Is_Contract_Only_Body
1349 (Defining_Unit_Name
(Specification
(Decl
)))
1356 end Analyze_Contract_Only_Bodies
;
1358 -- Start of processing for Analyze_Contract_Only_Subprograms
1361 if Ekind
(Current_Scope
) /= E_Package
then
1362 Analyze_Contract_Only_Bodies
;
1366 Pkg_Spec
: constant Node_Id
:=
1367 Package_Specification
(Current_Scope
);
1370 if not Has_Private_Declarations
(Pkg_Spec
) then
1371 Analyze_Contract_Only_Bodies
;
1373 -- For packages with private declarations, the contract-only
1374 -- bodies of subprograms defined in the visible part of the
1375 -- package are added to its private declarations (to ensure
1376 -- that they do not cause premature freezing of types and also
1377 -- that they are analyzed with proper visibility). Hence they
1378 -- will be analyzed later.
1380 elsif Visible_Declarations
(Pkg_Spec
) = L
then
1383 elsif Private_Declarations
(Pkg_Spec
) = L
then
1384 Analyze_Contract_Only_Bodies
;
1388 end Analyze_Contract_Only_Subprograms
;
1390 --------------------------------------
1391 -- Append_Contract_Only_Subprograms --
1392 --------------------------------------
1394 procedure Append_Contract_Only_Subprograms
(Subp_List
: List_Id
) is
1396 if No
(Subp_List
) then
1400 if Ekind
(Current_Scope
) /= E_Package
then
1401 Append_List
(Subp_List
, To
=> L
);
1405 Pkg_Spec
: constant Node_Id
:=
1406 Package_Specification
(Current_Scope
);
1409 if not Has_Private_Declarations
(Pkg_Spec
) then
1410 Append_List
(Subp_List
, To
=> L
);
1412 -- If the package has private declarations then append them to
1413 -- its private declarations; they will be analyzed when the
1414 -- contracts of its private declarations are analyzed.
1419 To
=> Private_Declarations
(Pkg_Spec
));
1423 end Append_Contract_Only_Subprograms
;
1425 ------------------------------------
1426 -- Build_Contract_Only_Subprogram --
1427 ------------------------------------
1429 -- This procedure takes care of building a wrapper to generate better
1430 -- analysis results in the case of a call to a subprogram whose body
1431 -- is unavailable to CodePeer but whose specification includes Pre/Post
1432 -- conditions. The body might be unavailable for any of a number or
1433 -- reasons (it is imported, the .adb file is simply missing, or the
1434 -- subprogram might be subject to an Annotate (CodePeer, Skip_Analysis)
1435 -- pragma). The built subprogram has the following contents:
1436 -- * check preconditions
1437 -- * call the subprogram
1438 -- * check postconditions
1440 function Build_Contract_Only_Subprogram
(E
: Entity_Id
) return Node_Id
is
1441 Loc
: constant Source_Ptr
:= Sloc
(E
);
1443 Missing_Body_Name
: constant Name_Id
:=
1444 New_External_Name
(Chars
(E
), "__missing_body");
1446 function Build_Missing_Body_Decls
return List_Id
;
1447 -- Build the declaration of the missing body subprogram and its
1448 -- corresponding pragma Import.
1450 function Build_Missing_Body_Subprogram_Call
return Node_Id
;
1451 -- Build the call to the missing body subprogram
1453 function Skip_Contract_Only_Subprogram
(E
: Entity_Id
) return Boolean;
1454 -- Return True for cases where the wrapper is not needed or we cannot
1457 ------------------------------
1458 -- Build_Missing_Body_Decls --
1459 ------------------------------
1461 function Build_Missing_Body_Decls
return List_Id
is
1462 Spec
: constant Node_Id
:= Declaration_Node
(E
);
1468 Make_Subprogram_Declaration
(Loc
, Copy_Subprogram_Spec
(Spec
));
1469 Set_Chars
(Defining_Entity
(Decl
), Missing_Body_Name
);
1473 Chars
=> Name_Import
,
1474 Pragma_Argument_Associations
=> New_List
(
1475 Make_Pragma_Argument_Association
(Loc
,
1476 Expression
=> Make_Identifier
(Loc
, Name_Ada
)),
1478 Make_Pragma_Argument_Association
(Loc
,
1479 Expression
=> Make_Identifier
(Loc
, Missing_Body_Name
))));
1481 return New_List
(Decl
, Prag
);
1482 end Build_Missing_Body_Decls
;
1484 ----------------------------------------
1485 -- Build_Missing_Body_Subprogram_Call --
1486 ----------------------------------------
1488 function Build_Missing_Body_Subprogram_Call
return Node_Id
is
1495 -- Build parameter list that we need
1497 Forml
:= First_Formal
(E
);
1498 while Present
(Forml
) loop
1499 Append_To
(Parms
, Make_Identifier
(Loc
, Chars
(Forml
)));
1500 Next_Formal
(Forml
);
1503 -- Build the call to the missing body subprogram
1505 if Ekind_In
(E
, E_Function
, E_Generic_Function
) then
1507 Make_Simple_Return_Statement
(Loc
,
1509 Make_Function_Call
(Loc
,
1511 Make_Identifier
(Loc
, Missing_Body_Name
),
1512 Parameter_Associations
=> Parms
));
1516 Make_Procedure_Call_Statement
(Loc
,
1518 Make_Identifier
(Loc
, Missing_Body_Name
),
1519 Parameter_Associations
=> Parms
);
1521 end Build_Missing_Body_Subprogram_Call
;
1523 -----------------------------------
1524 -- Skip_Contract_Only_Subprogram --
1525 -----------------------------------
1527 function Skip_Contract_Only_Subprogram
1528 (E
: Entity_Id
) return Boolean
1530 function Depends_On_Enclosing_Private_Type
return Boolean;
1531 -- Return True if some formal of E (or its return type) are
1532 -- private types defined in an enclosing package.
1534 function Some_Enclosing_Package_Has_Private_Decls
return Boolean;
1535 -- Return True if some enclosing package of the current scope has
1536 -- private declarations.
1538 ---------------------------------------
1539 -- Depends_On_Enclosing_Private_Type --
1540 ---------------------------------------
1542 function Depends_On_Enclosing_Private_Type
return Boolean is
1543 function Defined_In_Enclosing_Package
1544 (Typ
: Entity_Id
) return Boolean;
1545 -- Return True if Typ is an entity defined in an enclosing
1546 -- package of the current scope.
1548 ----------------------------------
1549 -- Defined_In_Enclosing_Package --
1550 ----------------------------------
1552 function Defined_In_Enclosing_Package
1553 (Typ
: Entity_Id
) return Boolean
1555 Scop
: Entity_Id
:= Scope
(Current_Scope
);
1558 while Scop
/= Scope
(Typ
)
1559 and then not Is_Compilation_Unit
(Scop
)
1561 Scop
:= Scope
(Scop
);
1564 return Scop
= Scope
(Typ
);
1565 end Defined_In_Enclosing_Package
;
1569 Param_E
: Entity_Id
;
1572 -- Start of processing for Depends_On_Enclosing_Private_Type
1575 Param_E
:= First_Entity
(E
);
1576 while Present
(Param_E
) loop
1577 Typ
:= Etype
(Param_E
);
1579 if Is_Private_Type
(Typ
)
1580 and then Defined_In_Enclosing_Package
(Typ
)
1585 Next_Entity
(Param_E
);
1589 Ekind
(E
) = E_Function
1590 and then Is_Private_Type
(Etype
(E
))
1591 and then Defined_In_Enclosing_Package
(Etype
(E
));
1592 end Depends_On_Enclosing_Private_Type
;
1594 ----------------------------------------------
1595 -- Some_Enclosing_Package_Has_Private_Decls --
1596 ----------------------------------------------
1598 function Some_Enclosing_Package_Has_Private_Decls
return Boolean is
1599 Scop
: Entity_Id
:= Current_Scope
;
1600 Pkg_Spec
: Node_Id
:= Package_Specification
(Scop
);
1604 if Ekind
(Scop
) = E_Package
1605 and then Has_Private_Declarations
1606 (Package_Specification
(Scop
))
1608 Pkg_Spec
:= Package_Specification
(Scop
);
1611 exit when Is_Compilation_Unit
(Scop
);
1612 Scop
:= Scope
(Scop
);
1615 return Pkg_Spec
/= Package_Specification
(Current_Scope
);
1616 end Some_Enclosing_Package_Has_Private_Decls
;
1618 -- Start of processing for Skip_Contract_Only_Subprogram
1621 if not CodePeer_Mode
1622 or else Inside_A_Generic
1623 or else not Is_Subprogram
(E
)
1624 or else Is_Abstract_Subprogram
(E
)
1625 or else Is_Imported
(E
)
1626 or else No
(Contract
(E
))
1627 or else No
(Pre_Post_Conditions
(Contract
(E
)))
1628 or else Is_Contract_Only_Body
(E
)
1629 or else Convention
(E
) = Convention_Protected
1633 -- We do not support building the contract-only subprogram if E
1634 -- is a subprogram declared in a nested package that has some
1635 -- formal or return type depending on a private type defined in
1636 -- an enclosing package.
1638 elsif Ekind
(Current_Scope
) = E_Package
1639 and then Some_Enclosing_Package_Has_Private_Decls
1640 and then Depends_On_Enclosing_Private_Type
1642 if Debug_Flag_Dot_KK
then
1644 Saved_Mode
: constant Warning_Mode_Type
:= Warning_Mode
;
1647 -- Warnings are disabled by default under CodePeer_Mode
1648 -- (see switch-c). Enable them temporarily.
1650 Warning_Mode
:= Normal
;
1652 ("cannot generate contract-only subprogram?", E
);
1653 Warning_Mode
:= Saved_Mode
;
1661 end Skip_Contract_Only_Subprogram
;
1663 -- Start of processing for Build_Contract_Only_Subprogram
1666 -- Test cases where the wrapper is not needed and cases where we
1669 if Skip_Contract_Only_Subprogram
(E
) then
1673 -- Note on calls to Copy_Separate_Tree. The trees we are copying
1674 -- here are fully analyzed, but we definitely want fully syntactic
1675 -- unanalyzed trees in the body we construct, so that the analysis
1676 -- generates the right visibility, and that is exactly what the
1677 -- calls to Copy_Separate_Tree give us.
1680 Name
: constant Name_Id
:=
1681 New_External_Name
(Chars
(E
), "__contract_only");
1687 Make_Subprogram_Body
(Loc
,
1689 Copy_Subprogram_Spec
(Declaration_Node
(E
)),
1691 Build_Missing_Body_Decls
,
1692 Handled_Statement_Sequence
=>
1693 Make_Handled_Sequence_Of_Statements
(Loc
,
1694 Statements
=> New_List
(
1695 Build_Missing_Body_Subprogram_Call
),
1696 End_Label
=> Make_Identifier
(Loc
, Name
)));
1698 Id
:= Defining_Unit_Name
(Specification
(Bod
));
1700 -- Copy only the pre/postconditions of the original contract
1701 -- since it is what we need, but also because pragmas stored in
1702 -- the other fields have N_Pragmas with N_Aspect_Specifications
1703 -- that reference their associated pragma (thus causing an endless
1704 -- loop when trying to copy the subtree).
1707 New_Contract
: constant Node_Id
:= Make_Contract
(Sloc
(E
));
1710 Set_Pre_Post_Conditions
(New_Contract
,
1711 Copy_Separate_Tree
(Pre_Post_Conditions
(Contract
(E
))));
1712 Set_Contract
(Id
, New_Contract
);
1715 -- Fix the name of this new subprogram and link the original
1716 -- subprogram with its Contract_Only_Body subprogram.
1718 Set_Chars
(Id
, Name
);
1719 Set_Is_Contract_Only_Body
(Id
);
1720 Set_Contract_Only_Body
(E
, Id
);
1724 end Build_Contract_Only_Subprogram
;
1726 -------------------------------------
1727 -- Build_Contract_Only_Subprograms --
1728 -------------------------------------
1730 function Build_Contract_Only_Subprograms
(L
: List_Id
) return List_Id
is
1733 Result
: List_Id
:= No_List
;
1734 Subp_Id
: Entity_Id
;
1738 while Present
(Decl
) loop
1739 if Nkind
(Decl
) = N_Subprogram_Declaration
then
1740 Subp_Id
:= Defining_Unit_Name
(Specification
(Decl
));
1741 New_Subp
:= Build_Contract_Only_Subprogram
(Subp_Id
);
1743 if Present
(New_Subp
) then
1748 Append_To
(Result
, New_Subp
);
1756 end Build_Contract_Only_Subprograms
;
1758 ------------------------------
1759 -- Has_Private_Declarations --
1760 ------------------------------
1762 function Has_Private_Declarations
(N
: Node_Id
) return Boolean is
1764 if not Nkind_In
(N
, N_Package_Specification
,
1765 N_Protected_Definition
,
1771 Present
(Private_Declarations
(N
))
1772 and then Is_Non_Empty_List
(Private_Declarations
(N
));
1774 end Has_Private_Declarations
;
1778 Subp_List
: List_Id
;
1780 -- Start of processing for Build_And_Analyze_Contract_Only_Subprograms
1783 Subp_List
:= Build_Contract_Only_Subprograms
(L
);
1784 Append_Contract_Only_Subprograms
(Subp_List
);
1785 Analyze_Contract_Only_Subprograms
;
1786 end Build_And_Analyze_Contract_Only_Subprograms
;
1788 -----------------------------
1789 -- Create_Generic_Contract --
1790 -----------------------------
1792 procedure Create_Generic_Contract
(Unit
: Node_Id
) is
1793 Templ
: constant Node_Id
:= Original_Node
(Unit
);
1794 Templ_Id
: constant Entity_Id
:= Defining_Entity
(Templ
);
1796 procedure Add_Generic_Contract_Pragma
(Prag
: Node_Id
);
1797 -- Add a single contract-related source pragma Prag to the contract of
1798 -- generic template Templ_Id.
1800 ---------------------------------
1801 -- Add_Generic_Contract_Pragma --
1802 ---------------------------------
1804 procedure Add_Generic_Contract_Pragma
(Prag
: Node_Id
) is
1805 Prag_Templ
: Node_Id
;
1808 -- Mark the pragma to prevent the premature capture of global
1809 -- references when capturing global references of the context
1810 -- (see Save_References_In_Pragma).
1812 Set_Is_Generic_Contract_Pragma
(Prag
);
1814 -- Pragmas that apply to a generic subprogram declaration are not
1815 -- part of the semantic structure of the generic template:
1818 -- procedure Example (Formal : Integer);
1819 -- pragma Precondition (Formal > 0);
1821 -- Create a generic template for such pragmas and link the template
1822 -- of the pragma with the generic template.
1824 if Nkind
(Templ
) = N_Generic_Subprogram_Declaration
then
1826 (Prag
, Copy_Generic_Node
(Prag
, Empty
, Instantiating
=> False));
1827 Prag_Templ
:= Original_Node
(Prag
);
1829 Set_Is_Generic_Contract_Pragma
(Prag_Templ
);
1830 Add_Contract_Item
(Prag_Templ
, Templ_Id
);
1832 -- Otherwise link the pragma with the generic template
1835 Add_Contract_Item
(Prag
, Templ_Id
);
1837 end Add_Generic_Contract_Pragma
;
1841 Context
: constant Node_Id
:= Parent
(Unit
);
1842 Decl
: Node_Id
:= Empty
;
1844 -- Start of processing for Create_Generic_Contract
1847 -- A generic package declaration carries contract-related source pragmas
1848 -- in its visible declarations.
1850 if Nkind
(Templ
) = N_Generic_Package_Declaration
then
1851 Set_Ekind
(Templ_Id
, E_Generic_Package
);
1853 if Present
(Visible_Declarations
(Specification
(Templ
))) then
1854 Decl
:= First
(Visible_Declarations
(Specification
(Templ
)));
1857 -- A generic package body carries contract-related source pragmas in its
1860 elsif Nkind
(Templ
) = N_Package_Body
then
1861 Set_Ekind
(Templ_Id
, E_Package_Body
);
1863 if Present
(Declarations
(Templ
)) then
1864 Decl
:= First
(Declarations
(Templ
));
1867 -- Generic subprogram declaration
1869 elsif Nkind
(Templ
) = N_Generic_Subprogram_Declaration
then
1870 if Nkind
(Specification
(Templ
)) = N_Function_Specification
then
1871 Set_Ekind
(Templ_Id
, E_Generic_Function
);
1873 Set_Ekind
(Templ_Id
, E_Generic_Procedure
);
1876 -- When the generic subprogram acts as a compilation unit, inspect
1877 -- the Pragmas_After list for contract-related source pragmas.
1879 if Nkind
(Context
) = N_Compilation_Unit
then
1880 if Present
(Aux_Decls_Node
(Context
))
1881 and then Present
(Pragmas_After
(Aux_Decls_Node
(Context
)))
1883 Decl
:= First
(Pragmas_After
(Aux_Decls_Node
(Context
)));
1886 -- Otherwise inspect the successive declarations for contract-related
1890 Decl
:= Next
(Unit
);
1893 -- A generic subprogram body carries contract-related source pragmas in
1894 -- its declarations.
1896 elsif Nkind
(Templ
) = N_Subprogram_Body
then
1897 Set_Ekind
(Templ_Id
, E_Subprogram_Body
);
1899 if Present
(Declarations
(Templ
)) then
1900 Decl
:= First
(Declarations
(Templ
));
1904 -- Inspect the relevant declarations looking for contract-related source
1905 -- pragmas and add them to the contract of the generic unit.
1907 while Present
(Decl
) loop
1908 if Comes_From_Source
(Decl
) then
1909 if Nkind
(Decl
) = N_Pragma
then
1911 -- The source pragma is a contract annotation
1913 if Is_Contract_Annotation
(Decl
) then
1914 Add_Generic_Contract_Pragma
(Decl
);
1917 -- The region where a contract-related source pragma may appear
1918 -- ends with the first source non-pragma declaration or statement.
1927 end Create_Generic_Contract
;
1929 --------------------------------
1930 -- Expand_Subprogram_Contract --
1931 --------------------------------
1933 procedure Expand_Subprogram_Contract
(Body_Id
: Entity_Id
) is
1934 Body_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Body_Id
);
1935 Spec_Id
: constant Entity_Id
:= Corresponding_Spec
(Body_Decl
);
1937 procedure Add_Invariant_And_Predicate_Checks
1938 (Subp_Id
: Entity_Id
;
1939 Stmts
: in out List_Id
;
1940 Result
: out Node_Id
);
1941 -- Process the result of function Subp_Id (if applicable) and all its
1942 -- formals. Add invariant and predicate checks where applicable. The
1943 -- routine appends all the checks to list Stmts. If Subp_Id denotes a
1944 -- function, Result contains the entity of parameter _Result, to be
1945 -- used in the creation of procedure _Postconditions.
1947 procedure Append_Enabled_Item
(Item
: Node_Id
; List
: in out List_Id
);
1948 -- Append a node to a list. If there is no list, create a new one. When
1949 -- the item denotes a pragma, it is added to the list only when it is
1952 procedure Build_Postconditions_Procedure
1953 (Subp_Id
: Entity_Id
;
1955 Result
: Entity_Id
);
1956 -- Create the body of procedure _Postconditions which handles various
1957 -- assertion actions on exit from subprogram Subp_Id. Stmts is the list
1958 -- of statements to be checked on exit. Parameter Result is the entity
1959 -- of parameter _Result when Subp_Id denotes a function.
1961 procedure Process_Contract_Cases
(Stmts
: in out List_Id
);
1962 -- Process pragma Contract_Cases. This routine prepends items to the
1963 -- body declarations and appends items to list Stmts.
1965 procedure Process_Postconditions
(Stmts
: in out List_Id
);
1966 -- Collect all [inherited] spec and body postconditions and accumulate
1967 -- their pragma Check equivalents in list Stmts.
1969 procedure Process_Preconditions
;
1970 -- Collect all [inherited] spec and body preconditions and prepend their
1971 -- pragma Check equivalents to the declarations of the body.
1973 ----------------------------------------
1974 -- Add_Invariant_And_Predicate_Checks --
1975 ----------------------------------------
1977 procedure Add_Invariant_And_Predicate_Checks
1978 (Subp_Id
: Entity_Id
;
1979 Stmts
: in out List_Id
;
1980 Result
: out Node_Id
)
1982 procedure Add_Invariant_Access_Checks
(Id
: Entity_Id
);
1983 -- Id denotes the return value of a function or a formal parameter.
1984 -- Add an invariant check if the type of Id is access to a type with
1985 -- invariants. The routine appends the generated code to Stmts.
1987 function Invariant_Checks_OK
(Typ
: Entity_Id
) return Boolean;
1988 -- Determine whether type Typ can benefit from invariant checks. To
1989 -- qualify, the type must have a non-null invariant procedure and
1990 -- subprogram Subp_Id must appear visible from the point of view of
1993 ---------------------------------
1994 -- Add_Invariant_Access_Checks --
1995 ---------------------------------
1997 procedure Add_Invariant_Access_Checks
(Id
: Entity_Id
) is
1998 Loc
: constant Source_Ptr
:= Sloc
(Body_Decl
);
2005 if Is_Access_Type
(Typ
) and then not Is_Access_Constant
(Typ
) then
2006 Typ
:= Designated_Type
(Typ
);
2008 if Invariant_Checks_OK
(Typ
) then
2010 Make_Explicit_Dereference
(Loc
,
2011 Prefix
=> New_Occurrence_Of
(Id
, Loc
));
2012 Set_Etype
(Ref
, Typ
);
2015 -- if <Id> /= null then
2016 -- <invariant_call (<Ref>)>
2021 Make_If_Statement
(Loc
,
2024 Left_Opnd
=> New_Occurrence_Of
(Id
, Loc
),
2025 Right_Opnd
=> Make_Null
(Loc
)),
2026 Then_Statements
=> New_List
(
2027 Make_Invariant_Call
(Ref
))),
2031 end Add_Invariant_Access_Checks
;
2033 -------------------------
2034 -- Invariant_Checks_OK --
2035 -------------------------
2037 function Invariant_Checks_OK
(Typ
: Entity_Id
) return Boolean is
2038 function Has_Public_Visibility_Of_Subprogram
return Boolean;
2039 -- Determine whether type Typ has public visibility of subprogram
2042 -----------------------------------------
2043 -- Has_Public_Visibility_Of_Subprogram --
2044 -----------------------------------------
2046 function Has_Public_Visibility_Of_Subprogram
return Boolean is
2047 Subp_Decl
: constant Node_Id
:= Unit_Declaration_Node
(Subp_Id
);
2050 -- An Initialization procedure must be considered visible even
2051 -- though it is internally generated.
2053 if Is_Init_Proc
(Defining_Entity
(Subp_Decl
)) then
2056 elsif Ekind
(Scope
(Typ
)) /= E_Package
then
2059 -- Internally generated code is never publicly visible except
2060 -- for a subprogram that is the implementation of an expression
2061 -- function. In that case the visibility is determined by the
2064 elsif not Comes_From_Source
(Subp_Decl
)
2066 (Nkind
(Original_Node
(Subp_Decl
)) /= N_Expression_Function
2068 Comes_From_Source
(Defining_Entity
(Subp_Decl
)))
2072 -- Determine whether the subprogram is declared in the visible
2073 -- declarations of the package containing the type, or in the
2074 -- visible declaration of a child unit of that package.
2078 Decls
: constant List_Id
:=
2079 List_Containing
(Subp_Decl
);
2080 Subp_Scope
: constant Entity_Id
:=
2081 Scope
(Defining_Entity
(Subp_Decl
));
2082 Typ_Scope
: constant Entity_Id
:= Scope
(Typ
);
2086 Decls
= Visible_Declarations
2087 (Specification
(Unit_Declaration_Node
(Typ_Scope
)))
2090 (Ekind
(Subp_Scope
) = E_Package
2091 and then Typ_Scope
/= Subp_Scope
2092 and then Is_Child_Unit
(Subp_Scope
)
2094 Is_Ancestor_Package
(Typ_Scope
, Subp_Scope
)
2096 Decls
= Visible_Declarations
2098 (Unit_Declaration_Node
(Subp_Scope
))));
2101 end Has_Public_Visibility_Of_Subprogram
;
2103 -- Start of processing for Invariant_Checks_OK
2107 Has_Invariants
(Typ
)
2108 and then Present
(Invariant_Procedure
(Typ
))
2109 and then not Has_Null_Body
(Invariant_Procedure
(Typ
))
2110 and then Has_Public_Visibility_Of_Subprogram
;
2111 end Invariant_Checks_OK
;
2115 Loc
: constant Source_Ptr
:= Sloc
(Body_Decl
);
2116 -- Source location of subprogram body contract
2121 -- Start of processing for Add_Invariant_And_Predicate_Checks
2126 -- Process the result of a function
2128 if Ekind
(Subp_Id
) = E_Function
then
2129 Typ
:= Etype
(Subp_Id
);
2131 -- Generate _Result which is used in procedure _Postconditions to
2132 -- verify the return value.
2134 Result
:= Make_Defining_Identifier
(Loc
, Name_uResult
);
2135 Set_Etype
(Result
, Typ
);
2137 -- Add an invariant check when the return type has invariants and
2138 -- the related function is visible to the outside.
2140 if Invariant_Checks_OK
(Typ
) then
2143 Make_Invariant_Call
(New_Occurrence_Of
(Result
, Loc
)),
2147 -- Add an invariant check when the return type is an access to a
2148 -- type with invariants.
2150 Add_Invariant_Access_Checks
(Result
);
2153 -- Add invariant and predicates for all formals that qualify
2155 Formal
:= First_Formal
(Subp_Id
);
2156 while Present
(Formal
) loop
2157 Typ
:= Etype
(Formal
);
2159 if Ekind
(Formal
) /= E_In_Parameter
2160 or else Is_Access_Type
(Typ
)
2162 if Invariant_Checks_OK
(Typ
) then
2165 Make_Invariant_Call
(New_Occurrence_Of
(Formal
, Loc
)),
2169 Add_Invariant_Access_Checks
(Formal
);
2171 -- Note: we used to add predicate checks for OUT and IN OUT
2172 -- formals here, but that was misguided, since such checks are
2173 -- performed on the caller side, based on the predicate of the
2174 -- actual, rather than the predicate of the formal.
2178 Next_Formal
(Formal
);
2180 end Add_Invariant_And_Predicate_Checks
;
2182 -------------------------
2183 -- Append_Enabled_Item --
2184 -------------------------
2186 procedure Append_Enabled_Item
(Item
: Node_Id
; List
: in out List_Id
) is
2188 -- Do not chain ignored or disabled pragmas
2190 if Nkind
(Item
) = N_Pragma
2191 and then (Is_Ignored
(Item
) or else Is_Disabled
(Item
))
2195 -- Otherwise, add the item
2202 -- If the pragma is a conjunct in a composite postcondition, it
2203 -- has been processed in reverse order. In the postcondition body
2204 -- it must appear before the others.
2206 if Nkind
(Item
) = N_Pragma
2207 and then From_Aspect_Specification
(Item
)
2208 and then Split_PPC
(Item
)
2210 Prepend
(Item
, List
);
2212 Append
(Item
, List
);
2215 end Append_Enabled_Item
;
2217 ------------------------------------
2218 -- Build_Postconditions_Procedure --
2219 ------------------------------------
2221 procedure Build_Postconditions_Procedure
2222 (Subp_Id
: Entity_Id
;
2226 procedure Insert_Before_First_Source_Declaration
(Stmt
: Node_Id
);
2227 -- Insert node Stmt before the first source declaration of the
2228 -- related subprogram's body. If no such declaration exists, Stmt
2229 -- becomes the last declaration.
2231 --------------------------------------------
2232 -- Insert_Before_First_Source_Declaration --
2233 --------------------------------------------
2235 procedure Insert_Before_First_Source_Declaration
(Stmt
: Node_Id
) is
2236 Decls
: constant List_Id
:= Declarations
(Body_Decl
);
2240 -- Inspect the declarations of the related subprogram body looking
2241 -- for the first source declaration.
2243 if Present
(Decls
) then
2244 Decl
:= First
(Decls
);
2245 while Present
(Decl
) loop
2246 if Comes_From_Source
(Decl
) then
2247 Insert_Before
(Decl
, Stmt
);
2254 -- If we get there, then the subprogram body lacks any source
2255 -- declarations. The body of _Postconditions now acts as the
2256 -- last declaration.
2258 Append
(Stmt
, Decls
);
2260 -- Ensure that the body has a declaration list
2263 Set_Declarations
(Body_Decl
, New_List
(Stmt
));
2265 end Insert_Before_First_Source_Declaration
;
2269 Loc
: constant Source_Ptr
:= Sloc
(Body_Decl
);
2270 Params
: List_Id
:= No_List
;
2272 Proc_Decl
: Node_Id
;
2273 Proc_Id
: Entity_Id
;
2274 Proc_Spec
: Node_Id
;
2276 -- Start of processing for Build_Postconditions_Procedure
2279 -- Nothing to do if there are no actions to check on exit
2285 Proc_Id
:= Make_Defining_Identifier
(Loc
, Name_uPostconditions
);
2286 Set_Debug_Info_Needed
(Proc_Id
);
2287 Set_Postconditions_Proc
(Subp_Id
, Proc_Id
);
2289 -- Force the front-end inlining of _Postconditions when generating C
2290 -- code, since its body may have references to itypes defined in the
2291 -- enclosing subprogram, which would cause problems for unnesting
2292 -- routines in the absence of inlining.
2294 if Modify_Tree_For_C
then
2295 Set_Has_Pragma_Inline
(Proc_Id
);
2296 Set_Has_Pragma_Inline_Always
(Proc_Id
);
2297 Set_Is_Inlined
(Proc_Id
);
2300 -- The related subprogram is a function: create the specification of
2301 -- parameter _Result.
2303 if Present
(Result
) then
2304 Params
:= New_List
(
2305 Make_Parameter_Specification
(Loc
,
2306 Defining_Identifier
=> Result
,
2308 New_Occurrence_Of
(Etype
(Result
), Loc
)));
2312 Make_Procedure_Specification
(Loc
,
2313 Defining_Unit_Name
=> Proc_Id
,
2314 Parameter_Specifications
=> Params
);
2316 Proc_Decl
:= Make_Subprogram_Declaration
(Loc
, Proc_Spec
);
2318 -- Insert _Postconditions before the first source declaration of the
2319 -- body. This ensures that the body will not cause any premature
2320 -- freezing, as it may mention types:
2322 -- procedure Proc (Obj : Array_Typ) is
2323 -- procedure _postconditions is
2326 -- end _postconditions;
2328 -- subtype T is Array_Typ (Obj'First (1) .. Obj'Last (1));
2331 -- In the example above, Obj is of type T but the incorrect placement
2332 -- of _Postconditions will cause a crash in gigi due to an out-of-
2333 -- order reference. The body of _Postconditions must be placed after
2334 -- the declaration of Temp to preserve correct visibility.
2336 Insert_Before_First_Source_Declaration
(Proc_Decl
);
2337 Analyze
(Proc_Decl
);
2339 -- Set an explicit End_Label to override the sloc of the implicit
2340 -- RETURN statement, and prevent it from inheriting the sloc of one
2341 -- the postconditions: this would cause confusing debug info to be
2342 -- produced, interfering with coverage-analysis tools.
2345 Make_Subprogram_Body
(Loc
,
2347 Copy_Subprogram_Spec
(Proc_Spec
),
2348 Declarations
=> Empty_List
,
2349 Handled_Statement_Sequence
=>
2350 Make_Handled_Sequence_Of_Statements
(Loc
,
2351 Statements
=> Stmts
,
2352 End_Label
=> Make_Identifier
(Loc
, Chars
(Proc_Id
))));
2354 Insert_After_And_Analyze
(Proc_Decl
, Proc_Bod
);
2355 end Build_Postconditions_Procedure
;
2357 ----------------------------
2358 -- Process_Contract_Cases --
2359 ----------------------------
2361 procedure Process_Contract_Cases
(Stmts
: in out List_Id
) is
2362 procedure Process_Contract_Cases_For
(Subp_Id
: Entity_Id
);
2363 -- Process pragma Contract_Cases for subprogram Subp_Id
2365 --------------------------------
2366 -- Process_Contract_Cases_For --
2367 --------------------------------
2369 procedure Process_Contract_Cases_For
(Subp_Id
: Entity_Id
) is
2370 Items
: constant Node_Id
:= Contract
(Subp_Id
);
2374 if Present
(Items
) then
2375 Prag
:= Contract_Test_Cases
(Items
);
2376 while Present
(Prag
) loop
2377 if Pragma_Name
(Prag
) = Name_Contract_Cases
2378 and then Is_Checked
(Prag
)
2380 Expand_Pragma_Contract_Cases
2383 Decls
=> Declarations
(Body_Decl
),
2387 Prag
:= Next_Pragma
(Prag
);
2390 end Process_Contract_Cases_For
;
2392 pragma Unmodified
(Stmts
);
2393 -- Stmts is passed as IN OUT to signal that the list can be updated,
2394 -- even if the corresponding integer value representing the list does
2397 -- Start of processing for Process_Contract_Cases
2400 Process_Contract_Cases_For
(Body_Id
);
2402 if Present
(Spec_Id
) then
2403 Process_Contract_Cases_For
(Spec_Id
);
2405 end Process_Contract_Cases
;
2407 ----------------------------
2408 -- Process_Postconditions --
2409 ----------------------------
2411 procedure Process_Postconditions
(Stmts
: in out List_Id
) is
2412 procedure Process_Body_Postconditions
(Post_Nam
: Name_Id
);
2413 -- Collect all [refined] postconditions of a specific kind denoted
2414 -- by Post_Nam that belong to the body, and generate pragma Check
2415 -- equivalents in list Stmts.
2417 procedure Process_Spec_Postconditions
;
2418 -- Collect all [inherited] postconditions of the spec, and generate
2419 -- pragma Check equivalents in list Stmts.
2421 ---------------------------------
2422 -- Process_Body_Postconditions --
2423 ---------------------------------
2425 procedure Process_Body_Postconditions
(Post_Nam
: Name_Id
) is
2426 Items
: constant Node_Id
:= Contract
(Body_Id
);
2427 Unit_Decl
: constant Node_Id
:= Parent
(Body_Decl
);
2432 -- Process the contract
2434 if Present
(Items
) then
2435 Prag
:= Pre_Post_Conditions
(Items
);
2436 while Present
(Prag
) loop
2437 if Pragma_Name
(Prag
) = Post_Nam
2438 and then Is_Checked
(Prag
)
2441 (Item
=> Build_Pragma_Check_Equivalent
(Prag
),
2445 Prag
:= Next_Pragma
(Prag
);
2449 -- The subprogram body being processed is actually the proper body
2450 -- of a stub with a corresponding spec. The subprogram stub may
2451 -- carry a postcondition pragma, in which case it must be taken
2452 -- into account. The pragma appears after the stub.
2454 if Present
(Spec_Id
) and then Nkind
(Unit_Decl
) = N_Subunit
then
2455 Decl
:= Next
(Corresponding_Stub
(Unit_Decl
));
2456 while Present
(Decl
) loop
2458 -- Note that non-matching pragmas are skipped
2460 if Nkind
(Decl
) = N_Pragma
then
2461 if Pragma_Name
(Decl
) = Post_Nam
2462 and then Is_Checked
(Decl
)
2465 (Item
=> Build_Pragma_Check_Equivalent
(Decl
),
2469 -- Skip internally generated code
2471 elsif not Comes_From_Source
(Decl
) then
2474 -- Postcondition pragmas are usually grouped together. There
2475 -- is no need to inspect the whole declarative list.
2484 end Process_Body_Postconditions
;
2486 ---------------------------------
2487 -- Process_Spec_Postconditions --
2488 ---------------------------------
2490 procedure Process_Spec_Postconditions
is
2491 Subps
: constant Subprogram_List
:=
2492 Inherited_Subprograms
(Spec_Id
);
2496 Subp_Id
: Entity_Id
;
2499 -- Process the contract
2501 Items
:= Contract
(Spec_Id
);
2503 if Present
(Items
) then
2504 Prag
:= Pre_Post_Conditions
(Items
);
2505 while Present
(Prag
) loop
2506 if Pragma_Name
(Prag
) = Name_Postcondition
2507 and then Is_Checked
(Prag
)
2510 (Item
=> Build_Pragma_Check_Equivalent
(Prag
),
2514 Prag
:= Next_Pragma
(Prag
);
2518 -- Process the contracts of all inherited subprograms, looking for
2519 -- class-wide postconditions.
2521 for Index
in Subps
'Range loop
2522 Subp_Id
:= Subps
(Index
);
2523 Items
:= Contract
(Subp_Id
);
2525 if Present
(Items
) then
2526 Prag
:= Pre_Post_Conditions
(Items
);
2527 while Present
(Prag
) loop
2528 if Pragma_Name
(Prag
) = Name_Postcondition
2529 and then Class_Present
(Prag
)
2532 Build_Pragma_Check_Equivalent
2535 Inher_Id
=> Subp_Id
);
2537 -- The pragma Check equivalent of the class-wide
2538 -- postcondition is still created even though the
2539 -- pragma may be ignored because the equivalent
2540 -- performs semantic checks.
2542 if Is_Checked
(Prag
) then
2543 Append_Enabled_Item
(Item
, Stmts
);
2547 Prag
:= Next_Pragma
(Prag
);
2551 end Process_Spec_Postconditions
;
2553 pragma Unmodified
(Stmts
);
2554 -- Stmts is passed as IN OUT to signal that the list can be updated,
2555 -- even if the corresponding integer value representing the list does
2558 -- Start of processing for Process_Postconditions
2561 -- The processing of postconditions is done in reverse order (body
2562 -- first) to ensure the following arrangement:
2564 -- <refined postconditions from body>
2565 -- <postconditions from body>
2566 -- <postconditions from spec>
2567 -- <inherited postconditions>
2569 Process_Body_Postconditions
(Name_Refined_Post
);
2570 Process_Body_Postconditions
(Name_Postcondition
);
2572 if Present
(Spec_Id
) then
2573 Process_Spec_Postconditions
;
2575 end Process_Postconditions
;
2577 ---------------------------
2578 -- Process_Preconditions --
2579 ---------------------------
2581 procedure Process_Preconditions
is
2582 Class_Pre
: Node_Id
:= Empty
;
2583 -- The sole [inherited] class-wide precondition pragma that applies
2584 -- to the subprogram.
2586 Insert_Node
: Node_Id
:= Empty
;
2587 -- The insertion node after which all pragma Check equivalents are
2590 function Is_Prologue_Renaming
(Decl
: Node_Id
) return Boolean;
2591 -- Determine whether arbitrary declaration Decl denotes a renaming of
2592 -- a discriminant or protection field _object.
2594 procedure Merge_Preconditions
(From
: Node_Id
; Into
: Node_Id
);
2595 -- Merge two class-wide preconditions by "or else"-ing them. The
2596 -- changes are accumulated in parameter Into. Update the error
2599 procedure Prepend_To_Decls
(Item
: Node_Id
);
2600 -- Prepend a single item to the declarations of the subprogram body
2602 procedure Prepend_To_Decls_Or_Save
(Prag
: Node_Id
);
2603 -- Save a class-wide precondition into Class_Pre, or prepend a normal
2604 -- precondition to the declarations of the body and analyze it.
2606 procedure Process_Inherited_Preconditions
;
2607 -- Collect all inherited class-wide preconditions and merge them into
2608 -- one big precondition to be evaluated as pragma Check.
2610 procedure Process_Preconditions_For
(Subp_Id
: Entity_Id
);
2611 -- Collect all preconditions of subprogram Subp_Id and prepend their
2612 -- pragma Check equivalents to the declarations of the body.
2614 --------------------------
2615 -- Is_Prologue_Renaming --
2616 --------------------------
2618 function Is_Prologue_Renaming
(Decl
: Node_Id
) return Boolean is
2625 if Nkind
(Decl
) = N_Object_Renaming_Declaration
then
2626 Obj
:= Defining_Entity
(Decl
);
2629 if Nkind
(Nam
) = N_Selected_Component
then
2630 Pref
:= Prefix
(Nam
);
2631 Sel
:= Selector_Name
(Nam
);
2633 -- A discriminant renaming appears as
2634 -- Discr : constant ... := Prefix.Discr;
2636 if Ekind
(Obj
) = E_Constant
2637 and then Is_Entity_Name
(Sel
)
2638 and then Present
(Entity
(Sel
))
2639 and then Ekind
(Entity
(Sel
)) = E_Discriminant
2643 -- A protection field renaming appears as
2644 -- Prot : ... := _object._object;
2646 -- A renamed private component is just a component of
2647 -- _object, with an arbitrary name.
2649 elsif Ekind
(Obj
) = E_Variable
2650 and then Nkind
(Pref
) = N_Identifier
2651 and then Chars
(Pref
) = Name_uObject
2652 and then Nkind
(Sel
) = N_Identifier
2660 end Is_Prologue_Renaming
;
2662 -------------------------
2663 -- Merge_Preconditions --
2664 -------------------------
2666 procedure Merge_Preconditions
(From
: Node_Id
; Into
: Node_Id
) is
2667 function Expression_Arg
(Prag
: Node_Id
) return Node_Id
;
2668 -- Return the boolean expression argument of a precondition while
2669 -- updating its parentheses count for the subsequent merge.
2671 function Message_Arg
(Prag
: Node_Id
) return Node_Id
;
2672 -- Return the message argument of a precondition
2674 --------------------
2675 -- Expression_Arg --
2676 --------------------
2678 function Expression_Arg
(Prag
: Node_Id
) return Node_Id
is
2679 Args
: constant List_Id
:= Pragma_Argument_Associations
(Prag
);
2680 Arg
: constant Node_Id
:= Get_Pragma_Arg
(Next
(First
(Args
)));
2683 if Paren_Count
(Arg
) = 0 then
2684 Set_Paren_Count
(Arg
, 1);
2694 function Message_Arg
(Prag
: Node_Id
) return Node_Id
is
2695 Args
: constant List_Id
:= Pragma_Argument_Associations
(Prag
);
2697 return Get_Pragma_Arg
(Last
(Args
));
2702 From_Expr
: constant Node_Id
:= Expression_Arg
(From
);
2703 From_Msg
: constant Node_Id
:= Message_Arg
(From
);
2704 Into_Expr
: constant Node_Id
:= Expression_Arg
(Into
);
2705 Into_Msg
: constant Node_Id
:= Message_Arg
(Into
);
2706 Loc
: constant Source_Ptr
:= Sloc
(Into
);
2708 -- Start of processing for Merge_Preconditions
2711 -- Merge the two preconditions by "or else"-ing them
2715 Right_Opnd
=> Relocate_Node
(Into_Expr
),
2716 Left_Opnd
=> From_Expr
));
2718 -- Merge the two error messages to produce a single message of the
2721 -- failed precondition from ...
2722 -- also failed inherited precondition from ...
2724 if not Exception_Locations_Suppressed
then
2725 Start_String
(Strval
(Into_Msg
));
2726 Store_String_Char
(ASCII
.LF
);
2727 Store_String_Chars
(" also ");
2728 Store_String_Chars
(Strval
(From_Msg
));
2730 Set_Strval
(Into_Msg
, End_String
);
2732 end Merge_Preconditions
;
2734 ----------------------
2735 -- Prepend_To_Decls --
2736 ----------------------
2738 procedure Prepend_To_Decls
(Item
: Node_Id
) is
2742 Decls
:= Declarations
(Body_Decl
);
2744 -- Ensure that the body has a declarative list
2748 Set_Declarations
(Body_Decl
, Decls
);
2751 Prepend_To
(Decls
, Item
);
2752 end Prepend_To_Decls
;
2754 ------------------------------
2755 -- Prepend_To_Decls_Or_Save --
2756 ------------------------------
2758 procedure Prepend_To_Decls_Or_Save
(Prag
: Node_Id
) is
2759 Check_Prag
: Node_Id
;
2762 Check_Prag
:= Build_Pragma_Check_Equivalent
(Prag
);
2764 -- Save the sole class-wide precondition (if any) for the next
2765 -- step, where it will be merged with inherited preconditions.
2767 if Class_Present
(Prag
) then
2768 pragma Assert
(No
(Class_Pre
));
2769 Class_Pre
:= Check_Prag
;
2771 -- Accumulate the corresponding Check pragmas at the top of the
2772 -- declarations. Prepending the items ensures that they will be
2773 -- evaluated in their original order.
2776 if Present
(Insert_Node
) then
2777 Insert_After
(Insert_Node
, Check_Prag
);
2779 Prepend_To_Decls
(Check_Prag
);
2782 Analyze
(Check_Prag
);
2784 end Prepend_To_Decls_Or_Save
;
2786 -------------------------------------
2787 -- Process_Inherited_Preconditions --
2788 -------------------------------------
2790 procedure Process_Inherited_Preconditions
is
2791 Subps
: constant Subprogram_List
:=
2792 Inherited_Subprograms
(Spec_Id
);
2797 Subp_Id
: Entity_Id
;
2800 -- Process the contracts of all inherited subprograms, looking for
2801 -- class-wide preconditions.
2803 for Index
in Subps
'Range loop
2804 Subp_Id
:= Subps
(Index
);
2805 Items
:= Contract
(Subp_Id
);
2807 if Present
(Items
) then
2808 Prag
:= Pre_Post_Conditions
(Items
);
2809 while Present
(Prag
) loop
2810 if Pragma_Name
(Prag
) = Name_Precondition
2811 and then Class_Present
(Prag
)
2814 Build_Pragma_Check_Equivalent
2817 Inher_Id
=> Subp_Id
);
2819 -- The pragma Check equivalent of the class-wide
2820 -- precondition is still created even though the
2821 -- pragma may be ignored because the equivalent
2822 -- performs semantic checks.
2824 if Is_Checked
(Prag
) then
2826 -- The spec of an inherited subprogram already
2827 -- yielded a class-wide precondition. Merge the
2828 -- existing precondition with the current one
2831 if Present
(Class_Pre
) then
2832 Merge_Preconditions
(Item
, Class_Pre
);
2839 Prag
:= Next_Pragma
(Prag
);
2844 -- Add the merged class-wide preconditions
2846 if Present
(Class_Pre
) then
2847 Prepend_To_Decls
(Class_Pre
);
2848 Analyze
(Class_Pre
);
2850 end Process_Inherited_Preconditions
;
2852 -------------------------------
2853 -- Process_Preconditions_For --
2854 -------------------------------
2856 procedure Process_Preconditions_For
(Subp_Id
: Entity_Id
) is
2857 Items
: constant Node_Id
:= Contract
(Subp_Id
);
2861 Subp_Decl
: Node_Id
;
2864 -- Process the contract
2866 if Present
(Items
) then
2867 Prag
:= Pre_Post_Conditions
(Items
);
2868 while Present
(Prag
) loop
2869 if Pragma_Name
(Prag
) = Name_Precondition
2870 and then Is_Checked
(Prag
)
2872 Prepend_To_Decls_Or_Save
(Prag
);
2875 Prag
:= Next_Pragma
(Prag
);
2879 -- The subprogram declaration being processed is actually a body
2880 -- stub. The stub may carry a precondition pragma, in which case
2881 -- it must be taken into account. The pragma appears after the
2884 Subp_Decl
:= Unit_Declaration_Node
(Subp_Id
);
2886 if Nkind
(Subp_Decl
) = N_Subprogram_Body_Stub
then
2888 -- Inspect the declarations following the body stub
2890 Decl
:= Next
(Subp_Decl
);
2891 while Present
(Decl
) loop
2893 -- Note that non-matching pragmas are skipped
2895 if Nkind
(Decl
) = N_Pragma
then
2896 if Pragma_Name
(Decl
) = Name_Precondition
2897 and then Is_Checked
(Decl
)
2899 Prepend_To_Decls_Or_Save
(Decl
);
2902 -- Skip internally generated code
2904 elsif not Comes_From_Source
(Decl
) then
2907 -- Preconditions are usually grouped together. There is no
2908 -- need to inspect the whole declarative list.
2917 end Process_Preconditions_For
;
2921 Decls
: constant List_Id
:= Declarations
(Body_Decl
);
2924 -- Start of processing for Process_Preconditions
2927 -- Find the proper insertion point for all pragma Check equivalents
2929 if Present
(Decls
) then
2930 Decl
:= First
(Decls
);
2931 while Present
(Decl
) loop
2933 -- First source declaration terminates the search, because all
2934 -- preconditions must be evaluated prior to it, by definition.
2936 if Comes_From_Source
(Decl
) then
2939 -- Certain internally generated object renamings such as those
2940 -- for discriminants and protection fields must be elaborated
2941 -- before the preconditions are evaluated, as their expressions
2942 -- may mention the discriminants. The renamings include those
2943 -- for private components so we need to find the last such.
2945 elsif Is_Prologue_Renaming
(Decl
) then
2946 while Present
(Next
(Decl
))
2947 and then Is_Prologue_Renaming
(Next
(Decl
))
2952 Insert_Node
:= Decl
;
2954 -- Otherwise the declaration does not come from source. This
2955 -- also terminates the search, because internal code may raise
2956 -- exceptions which should not preempt the preconditions.
2966 -- The processing of preconditions is done in reverse order (body
2967 -- first), because each pragma Check equivalent is inserted at the
2968 -- top of the declarations. This ensures that the final order is
2969 -- consistent with following diagram:
2971 -- <inherited preconditions>
2972 -- <preconditions from spec>
2973 -- <preconditions from body>
2975 Process_Preconditions_For
(Body_Id
);
2977 if Present
(Spec_Id
) then
2978 Process_Preconditions_For
(Spec_Id
);
2979 Process_Inherited_Preconditions
;
2981 end Process_Preconditions
;
2985 Restore_Scope
: Boolean := False;
2987 Stmts
: List_Id
:= No_List
;
2988 Subp_Id
: Entity_Id
;
2990 -- Start of processing for Expand_Subprogram_Contract
2993 -- Obtain the entity of the initial declaration
2995 if Present
(Spec_Id
) then
3001 -- Do not perform expansion activity when it is not needed
3003 if not Expander_Active
then
3006 -- ASIS requires an unaltered tree
3008 elsif ASIS_Mode
then
3011 -- GNATprove does not need the executable semantics of a contract
3013 elsif GNATprove_Mode
then
3016 -- The contract of a generic subprogram or one declared in a generic
3017 -- context is not expanded, as the corresponding instance will provide
3018 -- the executable semantics of the contract.
3020 elsif Is_Generic_Subprogram
(Subp_Id
) or else Inside_A_Generic
then
3023 -- All subprograms carry a contract, but for some it is not significant
3024 -- and should not be processed. This is a small optimization.
3026 elsif not Has_Significant_Contract
(Subp_Id
) then
3029 -- The contract of an ignored Ghost subprogram does not need expansion,
3030 -- because the subprogram and all calls to it will be removed.
3032 elsif Is_Ignored_Ghost_Entity
(Subp_Id
) then
3035 -- Do not re-expand the same contract. This scenario occurs when a
3036 -- construct is rewritten into something else during its analysis
3037 -- (expression functions for instance).
3039 elsif Has_Expanded_Contract
(Subp_Id
) then
3043 -- Prevent multiple expansion attempts of the same contract
3045 Set_Has_Expanded_Contract
(Subp_Id
);
3047 -- Ensure that the formal parameters are visible when expanding all
3050 if not In_Open_Scopes
(Subp_Id
) then
3051 Restore_Scope
:= True;
3052 Push_Scope
(Subp_Id
);
3054 if Is_Generic_Subprogram
(Subp_Id
) then
3055 Install_Generic_Formals
(Subp_Id
);
3057 Install_Formals
(Subp_Id
);
3061 -- The expansion of a subprogram contract involves the creation of Check
3062 -- pragmas to verify the contract assertions of the spec and body in a
3063 -- particular order. The order is as follows:
3065 -- function Example (...) return ... is
3066 -- procedure _Postconditions (...) is
3068 -- <refined postconditions from body>
3069 -- <postconditions from body>
3070 -- <postconditions from spec>
3071 -- <inherited postconditions>
3072 -- <contract case consequences>
3073 -- <invariant check of function result>
3074 -- <invariant and predicate checks of parameters>
3075 -- end _Postconditions;
3077 -- <inherited preconditions>
3078 -- <preconditions from spec>
3079 -- <preconditions from body>
3080 -- <contract case conditions>
3082 -- <source declarations>
3084 -- <source statements>
3086 -- _Preconditions (Result);
3090 -- Routine _Postconditions holds all contract assertions that must be
3091 -- verified on exit from the related subprogram.
3093 -- Step 1: Handle all preconditions. This action must come before the
3094 -- processing of pragma Contract_Cases because the pragma prepends items
3095 -- to the body declarations.
3097 Process_Preconditions
;
3099 -- Step 2: Handle all postconditions. This action must come before the
3100 -- processing of pragma Contract_Cases because the pragma appends items
3103 Process_Postconditions
(Stmts
);
3105 -- Step 3: Handle pragma Contract_Cases. This action must come before
3106 -- the processing of invariants and predicates because those append
3107 -- items to list Stmts.
3109 Process_Contract_Cases
(Stmts
);
3111 -- Step 4: Apply invariant and predicate checks on a function result and
3112 -- all formals. The resulting checks are accumulated in list Stmts.
3114 Add_Invariant_And_Predicate_Checks
(Subp_Id
, Stmts
, Result
);
3116 -- Step 5: Construct procedure _Postconditions
3118 Build_Postconditions_Procedure
(Subp_Id
, Stmts
, Result
);
3120 if Restore_Scope
then
3123 end Expand_Subprogram_Contract
;
3125 -------------------------------
3126 -- Freeze_Previous_Contracts --
3127 -------------------------------
3129 procedure Freeze_Previous_Contracts
(Body_Decl
: Node_Id
) is
3130 function Causes_Contract_Freezing
(N
: Node_Id
) return Boolean;
3131 pragma Inline
(Causes_Contract_Freezing
);
3132 -- Determine whether arbitrary node N causes contract freezing
3134 procedure Freeze_Contracts
;
3135 pragma Inline
(Freeze_Contracts
);
3136 -- Freeze the contracts of all eligible constructs which precede body
3139 procedure Freeze_Enclosing_Package_Body
;
3140 pragma Inline
(Freeze_Enclosing_Package_Body
);
3141 -- Freeze the contract of the nearest package body (if any) which
3142 -- encloses body Body_Decl.
3144 ------------------------------
3145 -- Causes_Contract_Freezing --
3146 ------------------------------
3148 function Causes_Contract_Freezing
(N
: Node_Id
) return Boolean is
3150 return Nkind_In
(N
, N_Entry_Body
,
3154 N_Subprogram_Body_Stub
,
3156 end Causes_Contract_Freezing
;
3158 ----------------------
3159 -- Freeze_Contracts --
3160 ----------------------
3162 procedure Freeze_Contracts
is
3163 Body_Id
: constant Entity_Id
:= Defining_Entity
(Body_Decl
);
3167 -- Nothing to do when the body which causes freezing does not appear
3168 -- in a declarative list because there cannot possibly be constructs
3171 if not Is_List_Member
(Body_Decl
) then
3175 -- Inspect the declarations preceding the body, and freeze individual
3176 -- contracts of eligible constructs.
3178 Decl
:= Prev
(Body_Decl
);
3179 while Present
(Decl
) loop
3181 -- Stop the traversal when a preceding construct that causes
3182 -- freezing is encountered as there is no point in refreezing
3183 -- the already frozen constructs.
3185 if Causes_Contract_Freezing
(Decl
) then
3188 -- Entry or subprogram declarations
3190 elsif Nkind_In
(Decl
, N_Abstract_Subprogram_Declaration
,
3191 N_Entry_Declaration
,
3192 N_Generic_Subprogram_Declaration
,
3193 N_Subprogram_Declaration
)
3195 Analyze_Entry_Or_Subprogram_Contract
3196 (Subp_Id
=> Defining_Entity
(Decl
),
3197 Freeze_Id
=> Body_Id
);
3201 elsif Nkind
(Decl
) = N_Object_Declaration
then
3202 Analyze_Object_Contract
3203 (Obj_Id
=> Defining_Entity
(Decl
),
3204 Freeze_Id
=> Body_Id
);
3208 elsif Nkind_In
(Decl
, N_Protected_Type_Declaration
,
3209 N_Single_Protected_Declaration
)
3211 Analyze_Protected_Contract
(Defining_Entity
(Decl
));
3213 -- Subprogram body stubs
3215 elsif Nkind
(Decl
) = N_Subprogram_Body_Stub
then
3216 Analyze_Subprogram_Body_Stub_Contract
(Defining_Entity
(Decl
));
3220 elsif Nkind_In
(Decl
, N_Single_Task_Declaration
,
3221 N_Task_Type_Declaration
)
3223 Analyze_Task_Contract
(Defining_Entity
(Decl
));
3228 end Freeze_Contracts
;
3230 -----------------------------------
3231 -- Freeze_Enclosing_Package_Body --
3232 -----------------------------------
3234 procedure Freeze_Enclosing_Package_Body
is
3235 Orig_Decl
: constant Node_Id
:= Original_Node
(Body_Decl
);
3239 -- Climb the parent chain looking for an enclosing package body. Do
3240 -- not use the scope stack, because a body utilizes the entity of its
3241 -- corresponding spec.
3243 Par
:= Parent
(Body_Decl
);
3244 while Present
(Par
) loop
3245 if Nkind
(Par
) = N_Package_Body
then
3246 Analyze_Package_Body_Contract
3247 (Body_Id
=> Defining_Entity
(Par
),
3248 Freeze_Id
=> Defining_Entity
(Body_Decl
));
3252 -- Do not look for an enclosing package body when the construct
3253 -- which causes freezing is a body generated for an expression
3254 -- function and it appears within a package spec. This ensures
3255 -- that the traversal will not reach too far up the parent chain
3256 -- and attempt to freeze a package body which must not be frozen.
3258 -- package body Enclosing_Body
3259 -- with Refined_State => (State => Var)
3261 -- package Nested is
3262 -- type Some_Type is ...;
3263 -- function Cause_Freezing return ...;
3265 -- function Cause_Freezing is (...);
3268 -- Var : Nested.Some_Type;
3270 elsif Nkind
(Par
) = N_Package_Declaration
3271 and then Nkind
(Orig_Decl
) = N_Expression_Function
3275 -- Prevent the search from going too far
3277 elsif Is_Body_Or_Package_Declaration
(Par
) then
3281 Par
:= Parent
(Par
);
3283 end Freeze_Enclosing_Package_Body
;
3287 Body_Id
: constant Entity_Id
:= Defining_Entity
(Body_Decl
);
3289 -- Start of processing for Freeze_Previous_Contracts
3292 pragma Assert
(Causes_Contract_Freezing
(Body_Decl
));
3294 -- A body that is in the process of being inlined appears from source,
3295 -- but carries name _parent. Such a body does not cause freezing of
3298 if Chars
(Body_Id
) = Name_uParent
then
3302 Freeze_Enclosing_Package_Body
;
3304 end Freeze_Previous_Contracts
;
3306 ---------------------------------
3307 -- Inherit_Subprogram_Contract --
3308 ---------------------------------
3310 procedure Inherit_Subprogram_Contract
3312 From_Subp
: Entity_Id
)
3314 procedure Inherit_Pragma
(Prag_Id
: Pragma_Id
);
3315 -- Propagate a pragma denoted by Prag_Id from From_Subp's contract to
3318 --------------------
3319 -- Inherit_Pragma --
3320 --------------------
3322 procedure Inherit_Pragma
(Prag_Id
: Pragma_Id
) is
3323 Prag
: constant Node_Id
:= Get_Pragma
(From_Subp
, Prag_Id
);
3327 -- A pragma cannot be part of more than one First_Pragma/Next_Pragma
3328 -- chains, therefore the node must be replicated. The new pragma is
3329 -- flagged as inherited for distinction purposes.
3331 if Present
(Prag
) then
3332 New_Prag
:= New_Copy_Tree
(Prag
);
3333 Set_Is_Inherited_Pragma
(New_Prag
);
3335 Add_Contract_Item
(New_Prag
, Subp
);
3339 -- Start of processing for Inherit_Subprogram_Contract
3342 -- Inheritance is carried out only when both entities are subprograms
3345 if Is_Subprogram_Or_Generic_Subprogram
(Subp
)
3346 and then Is_Subprogram_Or_Generic_Subprogram
(From_Subp
)
3347 and then Present
(Contract
(From_Subp
))
3349 Inherit_Pragma
(Pragma_Extensions_Visible
);
3351 end Inherit_Subprogram_Contract
;
3353 -------------------------------------
3354 -- Instantiate_Subprogram_Contract --
3355 -------------------------------------
3357 procedure Instantiate_Subprogram_Contract
(Templ
: Node_Id
; L
: List_Id
) is
3358 procedure Instantiate_Pragmas
(First_Prag
: Node_Id
);
3359 -- Instantiate all contract-related source pragmas found in the list,
3360 -- starting with pragma First_Prag. Each instantiated pragma is added
3363 -------------------------
3364 -- Instantiate_Pragmas --
3365 -------------------------
3367 procedure Instantiate_Pragmas
(First_Prag
: Node_Id
) is
3368 Inst_Prag
: Node_Id
;
3373 while Present
(Prag
) loop
3374 if Is_Generic_Contract_Pragma
(Prag
) then
3376 Copy_Generic_Node
(Prag
, Empty
, Instantiating
=> True);
3378 Set_Analyzed
(Inst_Prag
, False);
3379 Append_To
(L
, Inst_Prag
);
3382 Prag
:= Next_Pragma
(Prag
);
3384 end Instantiate_Pragmas
;
3388 Items
: constant Node_Id
:= Contract
(Defining_Entity
(Templ
));
3390 -- Start of processing for Instantiate_Subprogram_Contract
3393 if Present
(Items
) then
3394 Instantiate_Pragmas
(Pre_Post_Conditions
(Items
));
3395 Instantiate_Pragmas
(Contract_Test_Cases
(Items
));
3396 Instantiate_Pragmas
(Classifications
(Items
));
3398 end Instantiate_Subprogram_Contract
;
3400 ----------------------------------------
3401 -- Save_Global_References_In_Contract --
3402 ----------------------------------------
3404 procedure Save_Global_References_In_Contract
3408 procedure Save_Global_References_In_List
(First_Prag
: Node_Id
);
3409 -- Save all global references in contract-related source pragmas found
3410 -- in the list, starting with pragma First_Prag.
3412 ------------------------------------
3413 -- Save_Global_References_In_List --
3414 ------------------------------------
3416 procedure Save_Global_References_In_List
(First_Prag
: Node_Id
) is
3421 while Present
(Prag
) loop
3422 if Is_Generic_Contract_Pragma
(Prag
) then
3423 Save_Global_References
(Prag
);
3426 Prag
:= Next_Pragma
(Prag
);
3428 end Save_Global_References_In_List
;
3432 Items
: constant Node_Id
:= Contract
(Defining_Entity
(Templ
));
3434 -- Start of processing for Save_Global_References_In_Contract
3437 -- The entity of the analyzed generic copy must be on the scope stack
3438 -- to ensure proper detection of global references.
3440 Push_Scope
(Gen_Id
);
3442 if Permits_Aspect_Specifications
(Templ
)
3443 and then Has_Aspects
(Templ
)
3445 Save_Global_References_In_Aspects
(Templ
);
3448 if Present
(Items
) then
3449 Save_Global_References_In_List
(Pre_Post_Conditions
(Items
));
3450 Save_Global_References_In_List
(Contract_Test_Cases
(Items
));
3451 Save_Global_References_In_List
(Classifications
(Items
));
3455 end Save_Global_References_In_Contract
;