1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2014-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 Alloc
; use Alloc
;
27 with Aspects
; use Aspects
;
28 with Atree
; use Atree
;
29 with Einfo
; use Einfo
;
30 with Elists
; use Elists
;
31 with Errout
; use Errout
;
33 with Namet
; use Namet
;
34 with Nlists
; use Nlists
;
35 with Nmake
; use Nmake
;
38 with Sem_Aux
; use Sem_Aux
;
39 with Sem_Disp
; use Sem_Disp
;
40 with Sem_Eval
; use Sem_Eval
;
41 with Sem_Prag
; use Sem_Prag
;
42 with Sem_Res
; use Sem_Res
;
43 with Sem_Util
; use Sem_Util
;
44 with Sinfo
; use Sinfo
;
45 with Snames
; use Snames
;
50 -- The following table contains the N_Compilation_Unit node for a unit that
51 -- is either subject to pragma Ghost with policy Ignore or contains ignored
52 -- Ghost code. The table is used in the removal of ignored Ghost code from
55 package Ignored_Ghost_Units
is new Table
.Table
(
56 Table_Component_Type
=> Node_Id
,
57 Table_Index_Type
=> Int
,
59 Table_Initial
=> Alloc
.Ignored_Ghost_Units_Initial
,
60 Table_Increment
=> Alloc
.Ignored_Ghost_Units_Increment
,
61 Table_Name
=> "Ignored_Ghost_Units");
63 -----------------------
64 -- Local Subprograms --
65 -----------------------
67 function Ghost_Entity
(N
: Node_Id
) return Entity_Id
;
68 -- Subsidiary to Check_Ghost_Context and Set_Ghost_Mode. Find the entity of
69 -- a reference to a Ghost entity. Return Empty if there is no such entity.
71 function Is_Subject_To_Ghost
(N
: Node_Id
) return Boolean;
72 -- Subsidiary to routines Is_OK_xxx and Set_Ghost_Mode. Determine whether
73 -- declaration or body N is subject to aspect or pragma Ghost. Use this
74 -- routine in cases where [source] pragma Ghost has not been analyzed yet,
75 -- but the context needs to establish the "ghostness" of N.
77 procedure Propagate_Ignored_Ghost_Code
(N
: Node_Id
);
78 -- Subsidiary to routines Mark_xxx_As_Ghost and Set_Ghost_Mode_From_xxx.
79 -- Signal all enclosing scopes that they now contain ignored Ghost code.
80 -- Add the compilation unit containing N to table Ignored_Ghost_Units for
83 ----------------------------
84 -- Add_Ignored_Ghost_Unit --
85 ----------------------------
87 procedure Add_Ignored_Ghost_Unit
(Unit
: Node_Id
) is
89 pragma Assert
(Nkind
(Unit
) = N_Compilation_Unit
);
91 -- Avoid duplicates in the table as pruning the same unit more than once
92 -- is wasteful. Since ignored Ghost code tends to be grouped up, check
93 -- the contents of the table in reverse.
95 for Index
in reverse Ignored_Ghost_Units
.First
..
96 Ignored_Ghost_Units
.Last
98 -- If the unit is already present in the table, do not add it again
100 if Unit
= Ignored_Ghost_Units
.Table
(Index
) then
105 -- If we get here, then this is the first time the unit is being added
107 Ignored_Ghost_Units
.Append
(Unit
);
108 end Add_Ignored_Ghost_Unit
;
110 ----------------------------
111 -- Check_Ghost_Completion --
112 ----------------------------
114 procedure Check_Ghost_Completion
115 (Partial_View
: Entity_Id
;
116 Full_View
: Entity_Id
)
118 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
121 -- The Ghost policy in effect at the point of declaration and at the
122 -- point of completion must match (SPARK RM 6.9(14)).
124 if Is_Checked_Ghost_Entity
(Partial_View
)
125 and then Policy
= Name_Ignore
127 Error_Msg_Sloc
:= Sloc
(Full_View
);
129 Error_Msg_N
("incompatible ghost policies in effect", Partial_View
);
130 Error_Msg_N
("\& declared with ghost policy `Check`", Partial_View
);
131 Error_Msg_N
("\& completed # with ghost policy `Ignore`",
134 elsif Is_Ignored_Ghost_Entity
(Partial_View
)
135 and then Policy
= Name_Check
137 Error_Msg_Sloc
:= Sloc
(Full_View
);
139 Error_Msg_N
("incompatible ghost policies in effect", Partial_View
);
140 Error_Msg_N
("\& declared with ghost policy `Ignore`", Partial_View
);
141 Error_Msg_N
("\& completed # with ghost policy `Check`",
144 end Check_Ghost_Completion
;
146 -------------------------
147 -- Check_Ghost_Context --
148 -------------------------
150 procedure Check_Ghost_Context
(Ghost_Id
: Entity_Id
; Ghost_Ref
: Node_Id
) is
151 procedure Check_Ghost_Policy
(Id
: Entity_Id
; Err_N
: Node_Id
);
152 -- Verify that the Ghost policy at the point of declaration of entity Id
153 -- matches the policy at the point of reference. If this is not the case
154 -- emit an error at Err_N.
156 function Is_OK_Ghost_Context
(Context
: Node_Id
) return Boolean;
157 -- Determine whether node Context denotes a Ghost-friendly context where
158 -- a Ghost entity can safely reside (SPARK RM 6.9(10)).
160 -------------------------
161 -- Is_OK_Ghost_Context --
162 -------------------------
164 function Is_OK_Ghost_Context
(Context
: Node_Id
) return Boolean is
165 function Is_OK_Declaration
(Decl
: Node_Id
) return Boolean;
166 -- Determine whether node Decl is a suitable context for a reference
167 -- to a Ghost entity. To qualify as such, Decl must either
168 -- 1) Be subject to pragma Ghost
169 -- 2) Rename a Ghost entity
171 function Is_OK_Pragma
(Prag
: Node_Id
) return Boolean;
172 -- Determine whether node Prag is a suitable context for a reference
173 -- to a Ghost entity. To qualify as such, Prag must either
174 -- 1) Be an assertion expression pragma
175 -- 2) Denote pragma Global, Depends, Initializes, Refined_Global,
176 -- Refined_Depends or Refined_State
177 -- 3) Specify an aspect of a Ghost entity
178 -- 4) Contain a reference to a Ghost entity
180 function Is_OK_Statement
(Stmt
: Node_Id
) return Boolean;
181 -- Determine whether node Stmt is a suitable context for a reference
182 -- to a Ghost entity. To qualify as such, Stmt must either
183 -- 1) Denote a call to a Ghost procedure
184 -- 2) Denote an assignment statement whose target is Ghost
186 -----------------------
187 -- Is_OK_Declaration --
188 -----------------------
190 function Is_OK_Declaration
(Decl
: Node_Id
) return Boolean is
191 function In_Subprogram_Body_Profile
(N
: Node_Id
) return Boolean;
192 -- Determine whether node N appears in the profile of a subprogram
195 function Is_Ghost_Renaming
(Ren_Decl
: Node_Id
) return Boolean;
196 -- Determine whether node Ren_Decl denotes a renaming declaration
197 -- with a Ghost name.
199 --------------------------------
200 -- In_Subprogram_Body_Profile --
201 --------------------------------
203 function In_Subprogram_Body_Profile
(N
: Node_Id
) return Boolean is
204 Spec
: constant Node_Id
:= Parent
(N
);
207 -- The node appears in a parameter specification in which case
208 -- it is either the parameter type or the default expression or
209 -- the node appears as the result definition of a function.
212 (Nkind
(N
) = N_Parameter_Specification
214 (Nkind
(Spec
) = N_Function_Specification
215 and then N
= Result_Definition
(Spec
)))
216 and then Nkind
(Parent
(Spec
)) = N_Subprogram_Body
;
217 end In_Subprogram_Body_Profile
;
219 -----------------------
220 -- Is_Ghost_Renaming --
221 -----------------------
223 function Is_Ghost_Renaming
(Ren_Decl
: Node_Id
) return Boolean is
227 if Is_Renaming_Declaration
(Ren_Decl
) then
228 Nam_Id
:= Ghost_Entity
(Name
(Ren_Decl
));
230 return Present
(Nam_Id
) and then Is_Ghost_Entity
(Nam_Id
);
234 end Is_Ghost_Renaming
;
241 -- Start of processing for Is_OK_Declaration
244 if Is_Declaration
(Decl
) then
246 -- A renaming declaration is Ghost when it renames a Ghost
249 if Is_Ghost_Renaming
(Decl
) then
252 -- The declaration may not have been analyzed yet, determine
253 -- whether it is subject to pragma Ghost.
255 elsif Is_Subject_To_Ghost
(Decl
) then
261 -- A reference to a Ghost entity may appear within the profile of
262 -- a subprogram body. This context is treated as suitable because
263 -- it duplicates the context of the corresponding spec. The real
264 -- check was already performed during the analysis of the spec.
266 elsif In_Subprogram_Body_Profile
(Decl
) then
269 -- A reference to a Ghost entity may appear within an expression
270 -- function which is still being analyzed. This context is treated
271 -- as suitable because it is not yet known whether the expression
272 -- function is an initial declaration or a completion. The real
273 -- check is performed when the expression function is expanded.
275 elsif Nkind
(Decl
) = N_Expression_Function
276 and then not Analyzed
(Decl
)
280 -- References to Ghost entities may be relocated in internally
283 elsif Nkind
(Decl
) = N_Subprogram_Body
284 and then not Comes_From_Source
(Decl
)
286 Subp_Id
:= Corresponding_Spec
(Decl
);
288 if Present
(Subp_Id
) then
290 -- The context is the internally built _Postconditions
291 -- procedure, which is OK because the real check was done
292 -- before expansion activities.
294 if Chars
(Subp_Id
) = Name_uPostconditions
then
299 Original_Node
(Unit_Declaration_Node
(Subp_Id
));
301 -- The original context is an expression function that
302 -- has been split into a spec and a body. The context is
303 -- OK as long as the initial declaration is Ghost.
305 if Nkind
(Subp_Decl
) = N_Expression_Function
then
306 return Is_Subject_To_Ghost
(Subp_Decl
);
310 -- Otherwise this is either an internal body or an internal
311 -- completion. Both are OK because the real check was done
312 -- before expansion activities.
320 end Is_OK_Declaration
;
326 function Is_OK_Pragma
(Prag
: Node_Id
) return Boolean is
327 procedure Check_Policies
(Prag_Nam
: Name_Id
);
328 -- Verify that the Ghost policy in effect is the same as the
329 -- assertion policy for pragma name Prag_Nam. Emit an error if
330 -- this is not the case.
336 procedure Check_Policies
(Prag_Nam
: Name_Id
) is
337 AP
: constant Name_Id
:= Check_Kind
(Prag_Nam
);
338 GP
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
341 -- If the Ghost policy in effect at the point of a Ghost entity
342 -- reference is Ignore, then the assertion policy of the pragma
343 -- must be Ignore (SPARK RM 6.9(18)).
345 if GP
= Name_Ignore
and then AP
/= Name_Ignore
then
347 ("incompatible ghost policies in effect",
350 ("\ghost entity & has policy `Ignore`",
351 Ghost_Ref
, Ghost_Id
);
353 Error_Msg_Name_1
:= AP
;
355 ("\assertion expression has policy %", Ghost_Ref
);
366 -- Start of processing for Is_OK_Pragma
369 if Nkind
(Prag
) = N_Pragma
then
370 Prag_Id
:= Get_Pragma_Id
(Prag
);
371 Prag_Nam
:= Original_Aspect_Pragma_Name
(Prag
);
373 -- A pragma that applies to a Ghost construct or specifies an
374 -- aspect of a Ghost entity is a Ghost pragma (SPARK RM 6.9(3))
376 if Is_Ghost_Pragma
(Prag
) then
379 -- An assertion expression pragma is Ghost when it contains a
380 -- reference to a Ghost entity (SPARK RM 6.9(10)).
382 elsif Assertion_Expression_Pragma
(Prag_Id
) then
384 -- Ensure that the assertion policy and the Ghost policy are
385 -- compatible (SPARK RM 6.9(18)).
387 Check_Policies
(Prag_Nam
);
390 -- Several pragmas that may apply to a non-Ghost entity are
391 -- treated as Ghost when they contain a reference to a Ghost
392 -- entity (SPARK RM 6.9(11)).
394 elsif Nam_In
(Prag_Nam
, Name_Global
,
398 Name_Refined_Depends
,
403 -- Otherwise a normal pragma is Ghost when it encloses a Ghost
404 -- name (SPARK RM 6.9(3)).
407 Arg
:= First
(Pragma_Argument_Associations
(Prag
));
408 while Present
(Arg
) loop
409 Arg_Id
:= Ghost_Entity
(Get_Pragma_Arg
(Arg
));
411 if Present
(Arg_Id
) and then Is_Ghost_Entity
(Arg_Id
) then
423 ---------------------
424 -- Is_OK_Statement --
425 ---------------------
427 function Is_OK_Statement
(Stmt
: Node_Id
) return Boolean is
431 -- An assignment statement or a procedure call is Ghost when the
432 -- name denotes a Ghost entity.
434 if Nkind_In
(Stmt
, N_Assignment_Statement
,
435 N_Procedure_Call_Statement
)
437 Nam_Id
:= Ghost_Entity
(Name
(Stmt
));
439 return Present
(Nam_Id
) and then Is_Ghost_Entity
(Nam_Id
);
443 -- An if statement is a suitable context for a Ghost entity if it
444 -- is the byproduct of assertion expression expansion. Note that
445 -- the assertion expression may not be related to a Ghost entity,
446 -- but it may still contain references to Ghost entities.
448 elsif Nkind
(Stmt
) = N_If_Statement
449 and then Nkind
(Original_Node
(Stmt
)) = N_Pragma
450 and then Assertion_Expression_Pragma
451 (Get_Pragma_Id
(Original_Node
(Stmt
)))
463 -- Start of processing for Is_OK_Ghost_Context
466 -- The context is Ghost when it appears within a Ghost package or
469 if Ghost_Mode
> None
then
472 -- A Ghost type may be referenced in a use_type clause
473 -- (SPARK RM 6.9.10).
475 elsif Present
(Parent
(Context
))
476 and then Nkind
(Parent
(Context
)) = N_Use_Type_Clause
480 -- Routine Expand_Record_Extension creates a parent subtype without
481 -- inserting it into the tree. There is no good way of recognizing
482 -- this special case as there is no parent. Try to approximate the
485 elsif No
(Parent
(Context
)) and then Is_Tagged_Type
(Ghost_Id
) then
488 -- Otherwise climb the parent chain looking for a suitable Ghost
493 while Present
(Par
) loop
494 if Is_Ignored_Ghost_Node
(Par
) then
497 -- A reference to a Ghost entity can appear within an aspect
498 -- specification (SPARK RM 6.9(10)).
500 elsif Nkind
(Par
) = N_Aspect_Specification
then
503 elsif Is_OK_Declaration
(Par
) then
506 elsif Is_OK_Pragma
(Par
) then
509 elsif Is_OK_Statement
(Par
) then
512 -- Prevent the search from going too far
514 elsif Is_Body_Or_Package_Declaration
(Par
) then
521 -- The expansion of assertion expression pragmas and attribute Old
522 -- may cause a legal Ghost entity reference to become illegal due
523 -- to node relocation. Check the In_Assertion_Expr counter as last
524 -- resort to try and infer the original legal context.
526 if In_Assertion_Expr
> 0 then
529 -- Otherwise the context is not suitable for a reference to a
536 end Is_OK_Ghost_Context
;
538 ------------------------
539 -- Check_Ghost_Policy --
540 ------------------------
542 procedure Check_Ghost_Policy
(Id
: Entity_Id
; Err_N
: Node_Id
) is
543 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
546 -- The Ghost policy in effect a the point of declaration and at the
547 -- point of use must match (SPARK RM 6.9(13)).
549 if Is_Checked_Ghost_Entity
(Id
) and then Policy
= Name_Ignore
then
550 Error_Msg_Sloc
:= Sloc
(Err_N
);
552 Error_Msg_N
("incompatible ghost policies in effect", Err_N
);
553 Error_Msg_NE
("\& declared with ghost policy `Check`", Err_N
, Id
);
554 Error_Msg_NE
("\& used # with ghost policy `Ignore`", Err_N
, Id
);
556 elsif Is_Ignored_Ghost_Entity
(Id
) and then Policy
= Name_Check
then
557 Error_Msg_Sloc
:= Sloc
(Err_N
);
559 Error_Msg_N
("incompatible ghost policies in effect", Err_N
);
560 Error_Msg_NE
("\& declared with ghost policy `Ignore`", Err_N
, Id
);
561 Error_Msg_NE
("\& used # with ghost policy `Check`", Err_N
, Id
);
563 end Check_Ghost_Policy
;
565 -- Start of processing for Check_Ghost_Context
568 -- Once it has been established that the reference to the Ghost entity
569 -- is within a suitable context, ensure that the policy at the point of
570 -- declaration and at the point of use match.
572 if Is_OK_Ghost_Context
(Ghost_Ref
) then
573 Check_Ghost_Policy
(Ghost_Id
, Ghost_Ref
);
575 -- Otherwise the Ghost entity appears in a non-Ghost context and affects
576 -- its behavior or value (SPARK RM 6.9(11,12)).
579 Error_Msg_N
("ghost entity cannot appear in this context", Ghost_Ref
);
581 end Check_Ghost_Context
;
583 ----------------------------
584 -- Check_Ghost_Overriding --
585 ----------------------------
587 procedure Check_Ghost_Overriding
589 Overridden_Subp
: Entity_Id
)
591 Deriv_Typ
: Entity_Id
;
592 Over_Subp
: Entity_Id
;
595 if Present
(Subp
) and then Present
(Overridden_Subp
) then
596 Over_Subp
:= Ultimate_Alias
(Overridden_Subp
);
597 Deriv_Typ
:= Find_Dispatching_Type
(Subp
);
599 -- A Ghost primitive of a non-Ghost type extension cannot override an
600 -- inherited non-Ghost primitive (SPARK RM 6.9(8)).
602 if Is_Ghost_Entity
(Subp
)
603 and then Present
(Deriv_Typ
)
604 and then not Is_Ghost_Entity
(Deriv_Typ
)
605 and then not Is_Ghost_Entity
(Over_Subp
)
607 Error_Msg_N
("incompatible overriding in effect", Subp
);
609 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
610 Error_Msg_N
("\& declared # as non-ghost subprogram", Subp
);
612 Error_Msg_Sloc
:= Sloc
(Subp
);
613 Error_Msg_N
("\overridden # with ghost subprogram", Subp
);
616 -- A non-Ghost primitive of a type extension cannot override an
617 -- inherited Ghost primitive (SPARK RM 6.9(8)).
619 if not Is_Ghost_Entity
(Subp
)
620 and then Is_Ghost_Entity
(Over_Subp
)
622 Error_Msg_N
("incompatible overriding in effect", Subp
);
624 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
625 Error_Msg_N
("\& declared # as ghost subprogram", Subp
);
627 Error_Msg_Sloc
:= Sloc
(Subp
);
628 Error_Msg_N
("\overridden # with non-ghost subprogram", Subp
);
631 if Present
(Deriv_Typ
)
632 and then not Is_Ignored_Ghost_Entity
(Deriv_Typ
)
634 -- When a tagged type is either non-Ghost or checked Ghost and
635 -- one of its primitives overrides an inherited operation, the
636 -- overridden operation of the ancestor type must be ignored Ghost
637 -- if the primitive is ignored Ghost (SPARK RM 6.9(17)).
639 if Is_Ignored_Ghost_Entity
(Subp
) then
641 -- Both the parent subprogram and overriding subprogram are
644 if Is_Ignored_Ghost_Entity
(Over_Subp
) then
647 -- The parent subprogram carries policy Check
649 elsif Is_Checked_Ghost_Entity
(Over_Subp
) then
651 ("incompatible ghost policies in effect", Subp
);
653 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
655 ("\& declared # with ghost policy `Check`", Subp
);
657 Error_Msg_Sloc
:= Sloc
(Subp
);
659 ("\overridden # with ghost policy `Ignore`", Subp
);
661 -- The parent subprogram is non-Ghost
665 ("incompatible ghost policies in effect", Subp
);
667 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
668 Error_Msg_N
("\& declared # as non-ghost subprogram", Subp
);
670 Error_Msg_Sloc
:= Sloc
(Subp
);
672 ("\overridden # with ghost policy `Ignore`", Subp
);
675 -- When a tagged type is either non-Ghost or checked Ghost and
676 -- one of its primitives overrides an inherited operation, the
677 -- the primitive of the tagged type must be ignored Ghost if the
678 -- overridden operation is ignored Ghost (SPARK RM 6.9(17)).
680 elsif Is_Ignored_Ghost_Entity
(Over_Subp
) then
682 -- Both the parent subprogram and the overriding subprogram are
685 if Is_Ignored_Ghost_Entity
(Subp
) then
688 -- The overriding subprogram carries policy Check
690 elsif Is_Checked_Ghost_Entity
(Subp
) then
692 ("incompatible ghost policies in effect", Subp
);
694 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
696 ("\& declared # with ghost policy `Ignore`", Subp
);
698 Error_Msg_Sloc
:= Sloc
(Subp
);
700 ("\overridden # with Ghost policy `Check`", Subp
);
702 -- The overriding subprogram is non-Ghost
706 ("incompatible ghost policies in effect", Subp
);
708 Error_Msg_Sloc
:= Sloc
(Over_Subp
);
710 ("\& declared # with ghost policy `Ignore`", Subp
);
712 Error_Msg_Sloc
:= Sloc
(Subp
);
714 ("\overridden # with non-ghost subprogram", Subp
);
719 end Check_Ghost_Overriding
;
721 ---------------------------
722 -- Check_Ghost_Primitive --
723 ---------------------------
725 procedure Check_Ghost_Primitive
(Prim
: Entity_Id
; Typ
: Entity_Id
) is
727 -- The Ghost policy in effect at the point of declaration of a primitive
728 -- operation and a tagged type must match (SPARK RM 6.9(16)).
730 if Is_Tagged_Type
(Typ
) then
731 if Is_Checked_Ghost_Entity
(Prim
)
732 and then Is_Ignored_Ghost_Entity
(Typ
)
734 Error_Msg_N
("incompatible ghost policies in effect", Prim
);
736 Error_Msg_Sloc
:= Sloc
(Typ
);
738 ("\tagged type & declared # with ghost policy `Ignore`",
741 Error_Msg_Sloc
:= Sloc
(Prim
);
743 ("\primitive subprogram & declared # with ghost policy `Check`",
746 elsif Is_Ignored_Ghost_Entity
(Prim
)
747 and then Is_Checked_Ghost_Entity
(Typ
)
749 Error_Msg_N
("incompatible ghost policies in effect", Prim
);
751 Error_Msg_Sloc
:= Sloc
(Typ
);
753 ("\tagged type & declared # with ghost policy `Check`",
756 Error_Msg_Sloc
:= Sloc
(Prim
);
758 ("\primitive subprogram & declared # with ghost policy `Ignore`",
762 end Check_Ghost_Primitive
;
764 ----------------------------
765 -- Check_Ghost_Refinement --
766 ----------------------------
768 procedure Check_Ghost_Refinement
770 State_Id
: Entity_Id
;
772 Constit_Id
: Entity_Id
)
775 if Is_Ghost_Entity
(State_Id
) then
776 if Is_Ghost_Entity
(Constit_Id
) then
778 -- The Ghost policy in effect at the point of abstract state
779 -- declaration and constituent must match (SPARK RM 6.9(15)).
781 if Is_Checked_Ghost_Entity
(State_Id
)
782 and then Is_Ignored_Ghost_Entity
(Constit_Id
)
784 Error_Msg_Sloc
:= Sloc
(Constit
);
785 SPARK_Msg_N
("incompatible ghost policies in effect", State
);
788 ("\abstract state & declared with ghost policy `Check`",
791 ("\constituent & declared # with ghost policy `Ignore`",
794 elsif Is_Ignored_Ghost_Entity
(State_Id
)
795 and then Is_Checked_Ghost_Entity
(Constit_Id
)
797 Error_Msg_Sloc
:= Sloc
(Constit
);
798 SPARK_Msg_N
("incompatible ghost policies in effect", State
);
801 ("\abstract state & declared with ghost policy `Ignore`",
804 ("\constituent & declared # with ghost policy `Check`",
808 -- A constituent of a Ghost abstract state must be a Ghost entity
809 -- (SPARK RM 7.2.2(12)).
813 ("constituent of ghost state & must be ghost",
817 end Check_Ghost_Refinement
;
823 function Ghost_Entity
(N
: Node_Id
) return Entity_Id
is
827 -- When the reference extracts a subcomponent, recover the related
828 -- object (SPARK RM 6.9(1)).
831 while Nkind_In
(Ref
, N_Explicit_Dereference
,
833 N_Selected_Component
,
839 if Is_Entity_Name
(Ref
) then
846 --------------------------------
847 -- Implements_Ghost_Interface --
848 --------------------------------
850 function Implements_Ghost_Interface
(Typ
: Entity_Id
) return Boolean is
851 Iface_Elmt
: Elmt_Id
;
854 -- Traverse the list of interfaces looking for a Ghost interface
856 if Is_Tagged_Type
(Typ
) and then Present
(Interfaces
(Typ
)) then
857 Iface_Elmt
:= First_Elmt
(Interfaces
(Typ
));
858 while Present
(Iface_Elmt
) loop
859 if Is_Ghost_Entity
(Node
(Iface_Elmt
)) then
863 Next_Elmt
(Iface_Elmt
);
868 end Implements_Ghost_Interface
;
874 procedure Initialize
is
876 Ignored_Ghost_Units
.Init
;
879 -------------------------
880 -- Is_Subject_To_Ghost --
881 -------------------------
883 function Is_Subject_To_Ghost
(N
: Node_Id
) return Boolean is
884 function Enables_Ghostness
(Arg
: Node_Id
) return Boolean;
885 -- Determine whether aspect or pragma argument Arg enables "ghostness"
887 -----------------------
888 -- Enables_Ghostness --
889 -----------------------
891 function Enables_Ghostness
(Arg
: Node_Id
) return Boolean is
897 if Nkind
(Expr
) = N_Pragma_Argument_Association
then
898 Expr
:= Get_Pragma_Arg
(Expr
);
901 -- Determine whether the expression of the aspect or pragma is static
904 if Present
(Expr
) then
905 Preanalyze_And_Resolve
(Expr
);
908 Is_OK_Static_Expression
(Expr
)
909 and then Is_True
(Expr_Value
(Expr
));
911 -- Otherwise Ghost defaults to True
916 end Enables_Ghostness
;
920 Id
: constant Entity_Id
:= Defining_Entity
(N
);
925 -- Start of processing for Is_Subject_To_Ghost
928 -- The related entity of the declaration has not been analyzed yet, do
929 -- not inspect its attributes.
931 if Ekind
(Id
) = E_Void
then
934 elsif Is_Ghost_Entity
(Id
) then
937 -- The completion of a type or a constant is not fully analyzed when the
938 -- reference to the Ghost entity is resolved. Because the completion is
939 -- not marked as Ghost yet, inspect the partial view.
941 elsif Is_Record_Type
(Id
)
942 or else Ekind
(Id
) = E_Constant
943 or else (Nkind
(N
) = N_Object_Declaration
944 and then Constant_Present
(N
))
946 Prev_Id
:= Incomplete_Or_Partial_View
(Id
);
948 if Present
(Prev_Id
) and then Is_Ghost_Entity
(Prev_Id
) then
953 -- Examine the aspect specifications (if any) looking for aspect Ghost
955 if Permits_Aspect_Specifications
(N
) then
956 Asp
:= First
(Aspect_Specifications
(N
));
957 while Present
(Asp
) loop
958 if Chars
(Identifier
(Asp
)) = Name_Ghost
then
959 return Enables_Ghostness
(Expression
(Asp
));
968 -- When the context is a [generic] package declaration, pragma Ghost
969 -- resides in the visible declarations.
971 if Nkind_In
(N
, N_Generic_Package_Declaration
,
972 N_Package_Declaration
)
974 Decl
:= First
(Visible_Declarations
(Specification
(N
)));
976 -- When the context is a package or a subprogram body, pragma Ghost
977 -- resides in the declarative part.
979 elsif Nkind_In
(N
, N_Package_Body
, N_Subprogram_Body
) then
980 Decl
:= First
(Declarations
(N
));
982 -- Otherwise pragma Ghost appears in the declarations following N
984 elsif Is_List_Member
(N
) then
988 while Present
(Decl
) loop
989 if Nkind
(Decl
) = N_Pragma
990 and then Pragma_Name
(Decl
) = Name_Ghost
993 Enables_Ghostness
(First
(Pragma_Argument_Associations
(Decl
)));
995 -- A source construct ends the region where pragma Ghost may appear,
996 -- stop the traversal. Check the original node as source constructs
997 -- may be rewritten into something else by expansion.
999 elsif Comes_From_Source
(Original_Node
(Decl
)) then
1007 end Is_Subject_To_Ghost
;
1015 Ignored_Ghost_Units
.Locked
:= True;
1016 Ignored_Ghost_Units
.Release
;
1019 -----------------------------
1020 -- Mark_Full_View_As_Ghost --
1021 -----------------------------
1023 procedure Mark_Full_View_As_Ghost
1024 (Priv_Typ
: Entity_Id
;
1025 Full_Typ
: Entity_Id
)
1027 Full_Decl
: constant Node_Id
:= Declaration_Node
(Full_Typ
);
1030 if Is_Checked_Ghost_Entity
(Priv_Typ
) then
1031 Set_Is_Checked_Ghost_Entity
(Full_Typ
);
1033 elsif Is_Ignored_Ghost_Entity
(Priv_Typ
) then
1034 Set_Is_Ignored_Ghost_Entity
(Full_Typ
);
1035 Set_Is_Ignored_Ghost_Node
(Full_Decl
);
1036 Propagate_Ignored_Ghost_Code
(Full_Decl
);
1038 end Mark_Full_View_As_Ghost
;
1040 --------------------------
1041 -- Mark_Pragma_As_Ghost --
1042 --------------------------
1044 procedure Mark_Pragma_As_Ghost
1046 Context_Id
: Entity_Id
)
1049 if Is_Checked_Ghost_Entity
(Context_Id
) then
1050 Set_Is_Ghost_Pragma
(Prag
);
1052 elsif Is_Ignored_Ghost_Entity
(Context_Id
) then
1053 Set_Is_Ghost_Pragma
(Prag
);
1054 Set_Is_Ignored_Ghost_Node
(Prag
);
1055 Propagate_Ignored_Ghost_Code
(Prag
);
1057 end Mark_Pragma_As_Ghost
;
1059 ----------------------------
1060 -- Mark_Renaming_As_Ghost --
1061 ----------------------------
1063 procedure Mark_Renaming_As_Ghost
1064 (Ren_Decl
: Node_Id
;
1067 Ren_Id
: constant Entity_Id
:= Defining_Entity
(Ren_Decl
);
1070 if Is_Checked_Ghost_Entity
(Nam_Id
) then
1071 Set_Is_Checked_Ghost_Entity
(Ren_Id
);
1073 elsif Is_Ignored_Ghost_Entity
(Nam_Id
) then
1074 Set_Is_Ignored_Ghost_Entity
(Ren_Id
);
1075 Set_Is_Ignored_Ghost_Node
(Ren_Decl
);
1076 Propagate_Ignored_Ghost_Code
(Ren_Decl
);
1078 end Mark_Renaming_As_Ghost
;
1080 ----------------------------------
1081 -- Propagate_Ignored_Ghost_Code --
1082 ----------------------------------
1084 procedure Propagate_Ignored_Ghost_Code
(N
: Node_Id
) is
1089 -- Traverse the parent chain looking for blocks, packages and
1090 -- subprograms or their respective bodies.
1093 while Present
(Nod
) loop
1096 if Nkind
(Nod
) = N_Block_Statement
then
1097 Scop
:= Entity
(Identifier
(Nod
));
1099 elsif Nkind_In
(Nod
, N_Package_Body
,
1100 N_Package_Declaration
,
1102 N_Subprogram_Declaration
)
1104 Scop
:= Defining_Entity
(Nod
);
1107 -- The current node denotes a scoping construct
1109 if Present
(Scop
) then
1111 -- Stop the traversal when the scope already contains ignored
1112 -- Ghost code as all enclosing scopes have already been marked.
1114 if Contains_Ignored_Ghost_Code
(Scop
) then
1117 -- Otherwise mark this scope and keep climbing
1120 Set_Contains_Ignored_Ghost_Code
(Scop
);
1124 Nod
:= Parent
(Nod
);
1127 -- The unit containing the ignored Ghost code must be post processed
1128 -- before invoking the back end.
1130 Add_Ignored_Ghost_Unit
(Cunit
(Get_Code_Unit
(N
)));
1131 end Propagate_Ignored_Ghost_Code
;
1133 -------------------------------
1134 -- Remove_Ignored_Ghost_Code --
1135 -------------------------------
1137 procedure Remove_Ignored_Ghost_Code
is
1138 procedure Prune_Tree
(Root
: Node_Id
);
1139 -- Remove all code marked as ignored Ghost from the tree of denoted by
1146 procedure Prune_Tree
(Root
: Node_Id
) is
1147 procedure Prune
(N
: Node_Id
);
1148 -- Remove a given node from the tree by rewriting it into null
1150 function Prune_Node
(N
: Node_Id
) return Traverse_Result
;
1151 -- Determine whether node N denotes an ignored Ghost construct. If
1152 -- this is the case, rewrite N as a null statement. See the body for
1159 procedure Prune
(N
: Node_Id
) is
1161 -- Destroy any aspects that may be associated with the node
1163 if Permits_Aspect_Specifications
(N
) and then Has_Aspects
(N
) then
1167 Rewrite
(N
, Make_Null_Statement
(Sloc
(N
)));
1174 function Prune_Node
(N
: Node_Id
) return Traverse_Result
is
1178 -- The node is either declared as ignored Ghost or is a byproduct
1179 -- of expansion. Destroy it and stop the traversal on this branch.
1181 if Is_Ignored_Ghost_Node
(N
) then
1185 -- A freeze node for an ignored ghost entity must be pruned as
1186 -- well, to prevent meaningless references in the back end.
1188 -- ??? the freeze node itself should be ignored ghost
1190 elsif Nkind
(N
) = N_Freeze_Entity
1191 and then Is_Ignored_Ghost_Entity
(Entity
(N
))
1196 -- Scoping constructs such as blocks, packages, subprograms and
1197 -- bodies offer some flexibility with respect to pruning.
1199 elsif Nkind_In
(N
, N_Block_Statement
,
1201 N_Package_Declaration
,
1203 N_Subprogram_Declaration
)
1205 if Nkind
(N
) = N_Block_Statement
then
1206 Id
:= Entity
(Identifier
(N
));
1208 Id
:= Defining_Entity
(N
);
1211 -- The scoping construct contains both living and ignored Ghost
1212 -- code, let the traversal prune all relevant nodes.
1214 if Contains_Ignored_Ghost_Code
(Id
) then
1217 -- Otherwise the construct contains only living code and should
1224 -- Otherwise keep searching for ignored Ghost nodes
1231 procedure Prune_Nodes
is new Traverse_Proc
(Prune_Node
);
1233 -- Start of processing for Prune_Tree
1239 -- Start of processing for Remove_Ignored_Ghost_Code
1242 for Index
in Ignored_Ghost_Units
.First
.. Ignored_Ghost_Units
.Last
loop
1243 Prune_Tree
(Unit
(Ignored_Ghost_Units
.Table
(Index
)));
1245 end Remove_Ignored_Ghost_Code
;
1247 --------------------
1248 -- Set_Ghost_Mode --
1249 --------------------
1251 procedure Set_Ghost_Mode
(N
: Node_Id
; Id
: Entity_Id
:= Empty
) is
1252 procedure Set_From_Entity
(Ent_Id
: Entity_Id
);
1253 -- Set the value of global variable Ghost_Mode depending on the mode of
1256 procedure Set_From_Policy
;
1257 -- Set the value of global variable Ghost_Mode depending on the current
1258 -- Ghost policy in effect.
1260 ---------------------
1261 -- Set_From_Entity --
1262 ---------------------
1264 procedure Set_From_Entity
(Ent_Id
: Entity_Id
) is
1266 Set_Ghost_Mode_From_Entity
(Ent_Id
);
1268 if Is_Ignored_Ghost_Entity
(Ent_Id
) then
1269 Set_Is_Ignored_Ghost_Node
(N
);
1270 Propagate_Ignored_Ghost_Code
(N
);
1272 end Set_From_Entity
;
1274 ---------------------
1275 -- Set_From_Policy --
1276 ---------------------
1278 procedure Set_From_Policy
is
1279 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
1282 if Policy
= Name_Check
then
1283 Ghost_Mode
:= Check
;
1285 elsif Policy
= Name_Ignore
then
1286 Ghost_Mode
:= Ignore
;
1288 Set_Is_Ignored_Ghost_Node
(N
);
1289 Propagate_Ignored_Ghost_Code
(N
);
1291 end Set_From_Policy
;
1297 -- Start of processing for Set_Ghost_Mode
1300 -- The input node denotes one of the many declaration kinds that may be
1301 -- subject to pragma Ghost.
1303 if Is_Declaration
(N
) then
1304 if Is_Subject_To_Ghost
(N
) then
1307 -- The declaration denotes the completion of a deferred constant,
1308 -- pragma Ghost appears on the partial declaration.
1310 elsif Nkind
(N
) = N_Object_Declaration
1311 and then Constant_Present
(N
)
1312 and then Present
(Id
)
1314 Set_From_Entity
(Id
);
1316 -- The declaration denotes the full view of a private type, pragma
1317 -- Ghost appears on the partial declaration.
1319 elsif Nkind
(N
) = N_Full_Type_Declaration
1320 and then Is_Private_Type
(Defining_Entity
(N
))
1321 and then Present
(Id
)
1323 Set_From_Entity
(Id
);
1326 -- The input denotes an assignment or a procedure call. In this case
1327 -- the Ghost mode is dictated by the name of the construct.
1329 elsif Nkind_In
(N
, N_Assignment_Statement
,
1330 N_Procedure_Call_Statement
)
1332 Nam_Id
:= Ghost_Entity
(Name
(N
));
1334 if Present
(Nam_Id
) then
1335 Set_From_Entity
(Nam_Id
);
1338 -- The input denotes a package or subprogram body
1340 elsif Nkind_In
(N
, N_Package_Body
, N_Subprogram_Body
) then
1341 if (Present
(Id
) and then Is_Ghost_Entity
(Id
))
1342 or else Is_Subject_To_Ghost
(N
)
1347 -- The input denotes a pragma
1349 elsif Nkind
(N
) = N_Pragma
and then Is_Ghost_Pragma
(N
) then
1350 if Is_Ignored_Ghost_Node
(N
) then
1351 Ghost_Mode
:= Ignore
;
1353 Ghost_Mode
:= Check
;
1356 -- The input denotes a freeze node
1358 elsif Nkind
(N
) = N_Freeze_Entity
and then Present
(Id
) then
1359 Set_From_Entity
(Id
);
1363 --------------------------------
1364 -- Set_Ghost_Mode_From_Entity --
1365 --------------------------------
1367 procedure Set_Ghost_Mode_From_Entity
(Id
: Entity_Id
) is
1369 if Is_Checked_Ghost_Entity
(Id
) then
1370 Ghost_Mode
:= Check
;
1371 elsif Is_Ignored_Ghost_Entity
(Id
) then
1372 Ghost_Mode
:= Ignore
;
1374 end Set_Ghost_Mode_From_Entity
;
1376 -------------------------
1377 -- Set_Is_Ghost_Entity --
1378 -------------------------
1380 procedure Set_Is_Ghost_Entity
(Id
: Entity_Id
) is
1381 Policy
: constant Name_Id
:= Policy_In_Effect
(Name_Ghost
);
1383 if Policy
= Name_Check
then
1384 Set_Is_Checked_Ghost_Entity
(Id
);
1385 elsif Policy
= Name_Ignore
then
1386 Set_Is_Ignored_Ghost_Entity
(Id
);
1388 end Set_Is_Ghost_Entity
;